LCOV - code coverage report
Current view: top level - layout/painting - nsDisplayList.h (source / functions) Hit Total Coverage
Test: output.info Lines: 22 890 2.5 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       6             :  */
       7             : 
       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 "mozilla/Attributes.h"
      17             : #include "gfxContext.h"
      18             : #include "mozilla/ArenaAllocator.h"
      19             : #include "mozilla/Assertions.h"
      20             : #include "mozilla/Attributes.h"
      21             : #include "mozilla/Array.h"
      22             : #include "mozilla/DebugOnly.h"
      23             : #include "mozilla/EnumSet.h"
      24             : #include "mozilla/Maybe.h"
      25             : #include "mozilla/RefPtr.h"
      26             : #include "mozilla/TemplateLib.h" // mozilla::tl::Max
      27             : #include "nsCOMPtr.h"
      28             : #include "nsContainerFrame.h"
      29             : #include "nsPoint.h"
      30             : #include "nsRect.h"
      31             : #include "nsRegion.h"
      32             : #include "nsDisplayListInvalidation.h"
      33             : #include "DisplayItemClipChain.h"
      34             : #include "DisplayListClipState.h"
      35             : #include "LayerState.h"
      36             : #include "FrameMetrics.h"
      37             : #include "ImgDrawResult.h"
      38             : #include "mozilla/EffectCompositor.h"
      39             : #include "mozilla/EnumeratedArray.h"
      40             : #include "mozilla/Maybe.h"
      41             : #include "mozilla/UniquePtr.h"
      42             : #include "mozilla/TimeStamp.h"
      43             : #include "mozilla/gfx/UserData.h"
      44             : #include "mozilla/layers/LayerAttributes.h"
      45             : #include "nsCSSRenderingBorders.h"
      46             : #include "nsPresArena.h"
      47             : #include "nsAutoLayoutPhase.h"
      48             : #include "nsDisplayItemTypes.h"
      49             : #include "RetainedDisplayListHelpers.h"
      50             : 
      51             : #include <stdint.h>
      52             : #include "nsTHashtable.h"
      53             : 
      54             : #include <stdlib.h>
      55             : #include <algorithm>
      56             : #include <unordered_set>
      57             : 
      58             : class gfxContext;
      59             : class nsIContent;
      60             : class nsDisplayList;
      61             : class nsDisplayTableItem;
      62             : class nsIScrollableFrame;
      63             : class nsSubDocumentFrame;
      64             : class nsDisplayCompositorHitTestInfo;
      65             : class nsDisplayScrollInfoLayer;
      66             : class nsCaret;
      67             : enum class nsDisplayOwnLayerFlags;
      68             : 
      69             : namespace mozilla {
      70             : class FrameLayerBuilder;
      71             : namespace layers {
      72             : class Layer;
      73             : class ImageLayer;
      74             : class ImageContainer;
      75             : class StackingContextHelper;
      76             : class WebRenderCommand;
      77             : class WebRenderScrollData;
      78             : class WebRenderLayerScrollData;
      79             : } // namespace layers
      80             : namespace wr {
      81             : class DisplayListBuilder;
      82             : } // namespace wr
      83             : namespace dom {
      84             : class Selection;
      85             : } // namespace dom
      86             : } // namespace mozilla
      87             : 
      88             : // A set of blend modes, that never includes OP_OVER (since it's
      89             : // considered the default, rather than a specific blend mode).
      90             : typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
      91             : 
      92             : /*
      93             :  * An nsIFrame can have many different visual parts. For example an image frame
      94             :  * can have a background, border, and outline, the image itself, and a
      95             :  * translucent selection overlay. In general these parts can be drawn at
      96             :  * discontiguous z-levels; see CSS2.1 appendix E:
      97             :  * http://www.w3.org/TR/CSS21/zindex.html
      98             :  *
      99             :  * We construct a display list for a frame tree that contains one item
     100             :  * for each visual part. The display list is itself a tree since some items
     101             :  * are containers for other items; however, its structure does not match
     102             :  * the structure of its source frame tree. The display list items are sorted
     103             :  * by z-order. A display list can be used to paint the frames, to determine
     104             :  * which frame is the target of a mouse event, and to determine what areas
     105             :  * need to be repainted when scrolling. The display lists built for each task
     106             :  * may be different for efficiency; in particular some frames need special
     107             :  * display list items only for event handling, and do not create these items
     108             :  * when the display list will be used for painting (the common case). For
     109             :  * example, when painting we avoid creating nsDisplayBackground items for
     110             :  * frames that don't display a visible background, but for event handling
     111             :  * we need those backgrounds because they are not transparent to events.
     112             :  *
     113             :  * We could avoid constructing an explicit display list by traversing the
     114             :  * frame tree multiple times in clever ways. However, reifying the display list
     115             :  * reduces code complexity and reduces the number of times each frame must be
     116             :  * traversed to one, which seems to be good for performance. It also means
     117             :  * we can share code for painting, event handling and scroll analysis.
     118             :  *
     119             :  * Display lists are short-lived; content and frame trees cannot change
     120             :  * between a display list being created and destroyed. Display lists should
     121             :  * not be created during reflow because the frame tree may be in an
     122             :  * inconsistent state (e.g., a frame's stored overflow-area may not include
     123             :  * the bounds of all its children). However, it should be fine to create
     124             :  * a display list while a reflow is pending, before it starts.
     125             :  *
     126             :  * A display list covers the "extended" frame tree; the display list for a frame
     127             :  * tree containing FRAME/IFRAME elements can include frames from the subdocuments.
     128             :  *
     129             :  * Display item's coordinates are relative to their nearest reference frame ancestor.
     130             :  * Both the display root and any frame with a transform act as a reference frame
     131             :  * for their frame subtrees.
     132             :  */
     133             : 
     134             : // All types are defined in nsDisplayItemTypes.h
     135             : #define NS_DISPLAY_DECL_NAME(n, e) \
     136             :   virtual const char* Name() const override { return n; } \
     137             :   virtual DisplayItemType GetType() const override { return DisplayItemType::e; } \
     138             : private: \
     139             :   void* operator new(size_t aSize, \
     140             :                      nsDisplayListBuilder* aBuilder) { \
     141             :     return aBuilder->Allocate(aSize, DisplayItemType::e); \
     142             :   } \
     143             :   template<typename T, typename... Args> \
     144             :   friend T* ::MakeDisplayItem(nsDisplayListBuilder* aBuilder, Args&&... aArgs); \
     145             : public:
     146             : 
     147             : 
     148             : /**
     149             :  * Represents a frame that is considered to have (or will have) "animated geometry"
     150             :  * for itself and descendant frames.
     151             :  *
     152             :  * For example the scrolled frames of scrollframes which are actively being scrolled
     153             :  * fall into this category. Frames with certain CSS properties that are being animated
     154             :  * (e.g. 'left'/'top' etc) are also placed in this category. Frames with different
     155             :  * active geometry roots are in different PaintedLayers, so that we can animate the
     156             :  * geometry root by changing its transform (either on the main thread or in the
     157             :  * compositor).
     158             :  *
     159             :  * nsDisplayListBuilder constructs a tree of these (for fast traversals) and assigns
     160             :  * one for each display item.
     161             :  *
     162             :  * The animated geometry root for a display item is required to be a descendant (or
     163             :  * equal to) the item's ReferenceFrame(), which means that we will fall back to
     164             :  * returning aItem->ReferenceFrame() when we can't find another animated geometry root.
     165             :  *
     166             :  * The animated geometry root isn't strongly defined for a frame as transforms and
     167             :  * background-attachment:fixed can cause it to vary between display items for a given
     168             :  * frame.
     169             :  */
     170             : struct AnimatedGeometryRoot
     171             : {
     172             :   static already_AddRefed<AnimatedGeometryRoot>
     173             :   CreateAGRForFrame(nsIFrame* aFrame, AnimatedGeometryRoot* aParent, bool aIsAsync, bool aIsRetained)
     174             :   {
     175             :     RefPtr<AnimatedGeometryRoot> result;
     176             :     if (aIsRetained) {
     177             :       result = aFrame->GetProperty(AnimatedGeometryRootCache());
     178             :     }
     179             : 
     180             :     if (result) {
     181             :       result->mParentAGR = aParent;
     182             :       result->mIsAsync = aIsAsync;
     183             :     } else {
     184             :       result = new AnimatedGeometryRoot(aFrame, aParent, aIsAsync, aIsRetained);
     185             :     }
     186             :     return result.forget();
     187             :   }
     188             : 
     189             :   operator nsIFrame*() { return mFrame; }
     190             : 
     191             :   nsIFrame* operator ->() const { return mFrame; }
     192             : 
     193             :   AnimatedGeometryRoot* GetAsyncAGR() {
     194             :     AnimatedGeometryRoot* agr = this;
     195             :     while (!agr->mIsAsync && agr->mParentAGR) {
     196             :       agr = agr->mParentAGR;
     197             :     }
     198             :     return agr;
     199             :   }
     200             : 
     201           0 :   NS_INLINE_DECL_REFCOUNTING(AnimatedGeometryRoot)
     202             : 
     203             :   nsIFrame* mFrame;
     204             :   RefPtr<AnimatedGeometryRoot> mParentAGR;
     205             :   bool mIsAsync;
     206             :   bool mIsRetained;
     207             : 
     208             : protected:
     209           0 :   static void DetachAGR(AnimatedGeometryRoot* aAGR) {
     210           0 :     aAGR->mFrame = nullptr;
     211           0 :     aAGR->mParentAGR = nullptr;
     212           0 :     NS_RELEASE(aAGR);
     213           0 :   }
     214             :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(AnimatedGeometryRootCache, AnimatedGeometryRoot, DetachAGR)
     215             : 
     216             :   AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent, bool aIsAsync, bool aIsRetained)
     217             :     : mFrame(aFrame)
     218             :     , mParentAGR(aParent)
     219             :     , mIsAsync(aIsAsync)
     220             :     , mIsRetained(aIsRetained)
     221             :   {
     222             :     MOZ_ASSERT(mParentAGR || mIsAsync, "The root AGR should always be treated as an async AGR.");
     223             :     if (mIsRetained) {
     224             :       NS_ADDREF(this);
     225             :       aFrame->SetProperty(AnimatedGeometryRootCache(), this);
     226             :     }
     227             :   }
     228             : 
     229           0 :   ~AnimatedGeometryRoot()
     230           0 :   {
     231           0 :     if (mFrame && mIsRetained) {
     232           0 :       mFrame->DeleteProperty(AnimatedGeometryRootCache());
     233             :     }
     234           0 :   }
     235             : };
     236             : 
     237             : namespace mozilla {
     238             : 
     239             : /**
     240             :  * An active scrolled root (ASR) is similar to an animated geometry root (AGR).
     241             :  * The differences are:
     242             :  *  - ASRs are only created for async-scrollable scroll frames. This is a
     243             :  *    (hopefully) temporary restriction. In the future we will want to create
     244             :  *    ASRs for all the things that are currently creating AGRs, and then
     245             :  *    replace AGRs with ASRs and rename them from "active scrolled root" to
     246             :  *    "animated geometry root".
     247             :  *  - ASR objects are created during display list construction by the nsIFrames
     248             :  *    that induce ASRs. This is done using AutoCurrentActiveScrolledRootSetter.
     249             :  *    The current ASR is returned by nsDisplayListBuilder::CurrentActiveScrolledRoot().
     250             :  *  - There is no way to go from an nsIFrame pointer to the ASR of that frame.
     251             :  *    If you need to look up an ASR after display list construction, you need
     252             :  *    to store it while the AutoCurrentActiveScrolledRootSetter that creates it
     253             :  *    is on the stack.
     254             :  */
     255             : struct ActiveScrolledRoot {
     256             :   static already_AddRefed<ActiveScrolledRoot>
     257             :   CreateASRForFrame(const ActiveScrolledRoot* aParent,
     258             :                     nsIScrollableFrame* aScrollableFrame,
     259             :                     bool aIsRetained)
     260             :   {
     261             :     nsIFrame* f = do_QueryFrame(aScrollableFrame);
     262             : 
     263             :     RefPtr<ActiveScrolledRoot> asr;
     264             :     if (aIsRetained) {
     265             :       asr = f->GetProperty(ActiveScrolledRootCache());
     266             :     }
     267             : 
     268             :     if (!asr) {
     269             :       asr = new ActiveScrolledRoot();
     270             : 
     271             :       if (aIsRetained) {
     272             :         RefPtr<ActiveScrolledRoot> ref = asr;
     273             :         f->SetProperty(ActiveScrolledRootCache(), ref.forget().take());
     274             :       }
     275             :     }
     276             :     asr->mParent = aParent;
     277             :     asr->mScrollableFrame = aScrollableFrame;
     278             :     asr->mViewId = Nothing();
     279             :     asr->mDepth = aParent ? aParent->mDepth + 1 : 1;
     280             :     asr->mRetained = aIsRetained;
     281             : 
     282             :     return asr.forget();
     283             :   }
     284             : 
     285             :   static const ActiveScrolledRoot* PickAncestor(const ActiveScrolledRoot* aOne,
     286             :                                                 const ActiveScrolledRoot* aTwo)
     287             :   {
     288             :     MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
     289             :     return Depth(aOne) <= Depth(aTwo) ? aOne : aTwo;
     290             :   }
     291             : 
     292           2 :   static const ActiveScrolledRoot* PickDescendant(const ActiveScrolledRoot* aOne,
     293             :                                                   const ActiveScrolledRoot* aTwo)
     294             :   {
     295           2 :     MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
     296           2 :     return Depth(aOne) >= Depth(aTwo) ? aOne : aTwo;
     297             :   }
     298             : 
     299             :   static bool IsAncestor(const ActiveScrolledRoot* aAncestor,
     300             :                          const ActiveScrolledRoot* aDescendant);
     301             : 
     302             :   static nsCString ToString(const mozilla::ActiveScrolledRoot* aActiveScrolledRoot);
     303             : 
     304             :   // Call this when inserting an ancestor.
     305             :   void IncrementDepth() { mDepth++; }
     306             : 
     307             :   /**
     308             :    * Find the view ID (or generate a new one) for the content element
     309             :    * corresponding to the ASR.
     310             :    */
     311           0 :   mozilla::layers::FrameMetrics::ViewID GetViewId() const {
     312           0 :     if (!mViewId.isSome()) {
     313           0 :       nsIContent* content = mScrollableFrame->GetScrolledFrame()->GetContent();
     314           0 :       mViewId = Some(nsLayoutUtils::FindOrCreateIDFor(content));
     315             :     }
     316           0 :     return *mViewId;
     317             :   }
     318             : 
     319             :   RefPtr<const ActiveScrolledRoot> mParent;
     320             :   nsIScrollableFrame* mScrollableFrame;
     321             : 
     322           0 :   NS_INLINE_DECL_REFCOUNTING(ActiveScrolledRoot)
     323             : 
     324             : private:
     325             :   ActiveScrolledRoot()
     326             :     : mScrollableFrame(nullptr)
     327             :     , mDepth(0)
     328             :     , mRetained(false)
     329           0 :   {
     330           0 :   }
     331           0 : 
     332           0 :   ~ActiveScrolledRoot()
     333           0 :   {
     334             :     if (mScrollableFrame && mRetained) {
     335           0 :       nsIFrame* f = do_QueryFrame(mScrollableFrame);
     336             :       f->DeleteProperty(ActiveScrolledRootCache());
     337           0 :     }
     338           0 :   }
     339           0 : 
     340           0 :   static void DetachASR(ActiveScrolledRoot* aASR) {
     341           0 :     aASR->mParent = nullptr;
     342             :     aASR->mScrollableFrame = nullptr;
     343             :     NS_RELEASE(aASR);
     344             :   }
     345           0 :   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(ActiveScrolledRootCache, ActiveScrolledRoot, DetachASR)
     346             : 
     347             :   static uint32_t Depth(const ActiveScrolledRoot* aActiveScrolledRoot) {
     348             :     return aActiveScrolledRoot ? aActiveScrolledRoot->mDepth : 0;
     349             :   }
     350             : 
     351             :   // This field is lazily populated in GetViewId(). We don't want to do the
     352             :   // work of populating if webrender is disabled, because it is often not
     353             :   // needed.
     354             :   mutable Maybe<mozilla::layers::FrameMetrics::ViewID> mViewId;
     355             : 
     356             :   uint32_t mDepth;
     357             :   bool mRetained;
     358             : };
     359             : 
     360             : }
     361             : 
     362             : enum class nsDisplayListBuilderMode : uint8_t {
     363             :   PAINTING,
     364             :   EVENT_DELIVERY,
     365             :   PLUGIN_GEOMETRY,
     366             :   FRAME_VISIBILITY,
     367             :   TRANSFORM_COMPUTATION,
     368             :   GENERATE_GLYPH,
     369             :   PAINTING_SELECTION_BACKGROUND
     370             : };
     371             : 
     372             : /**
     373             :  * This manages a display list and is passed as a parameter to
     374             :  * nsIFrame::BuildDisplayList.
     375             :  * It contains the parameters that don't change from frame to frame and manages
     376             :  * the display list memory using an arena. It also establishes the reference
     377             :  * coordinate system for all display list items. Some of the parameters are
     378             :  * available from the prescontext/presshell, but we copy them into the builder
     379             :  * for faster/more convenient access.
     380             :  */
     381             : class nsDisplayListBuilder {
     382             :   typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
     383             :   typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
     384             : 
     385             :   /**
     386             :    * This manages status of a 3d context to collect visible rects of
     387             :    * descendants and passing a dirty rect.
     388             :    *
     389             :    * Since some transforms maybe singular, passing visible rects or
     390             :    * the dirty rect level by level from parent to children may get a
     391             :    * wrong result, being different from the result of appling with
     392             :    * effective transform directly.
     393             :    *
     394             :    * nsFrame::BuildDisplayListForStackingContext() uses
     395             :    * AutoPreserves3DContext to install an instance on the builder.
     396             :    *
     397             :    * \see AutoAccumulateTransform, AutoAccumulateRect,
     398             :    *      AutoPreserves3DContext, Accumulate, GetCurrentTransform,
     399             :    *      StartRoot.
     400             :    */
     401             :   class Preserves3DContext {
     402             :   public:
     403             :     typedef mozilla::gfx::Matrix4x4 Matrix4x4;
     404             : 
     405             :     Preserves3DContext()
     406             :       : mAccumulatedRectLevels(0)
     407             :     {}
     408             :     Preserves3DContext(const Preserves3DContext &aOther)
     409             :       : mAccumulatedTransform()
     410             :       , mAccumulatedRect()
     411             :       , mAccumulatedRectLevels(0)
     412             :       , mVisibleRect(aOther.mVisibleRect) {}
     413             : 
     414             :     // Accmulate transforms of ancestors on the preserves-3d chain.
     415             :     Matrix4x4 mAccumulatedTransform;
     416             :     // Accmulate visible rect of descendants in the preserves-3d context.
     417             :     nsRect mAccumulatedRect;
     418             :     // How far this frame is from the root of the current 3d context.
     419             :     int mAccumulatedRectLevels;
     420             :     nsRect mVisibleRect;
     421             :   };
     422             : 
     423             :   /**
     424             :    * A frame can be in one of three states of AGR.
     425             :    * AGR_NO     means the frame is not an AGR for now.
     426             :    * AGR_YES    means the frame is an AGR for now.
     427             :    * AGR_MAYBE  means the frame is not an AGR for now, but a transition
     428             :    *            to AGR_YES without restyling is possible.
     429             :    */
     430             :   enum AGRState { AGR_NO, AGR_YES, AGR_MAYBE };
     431             : 
     432             : public:
     433             :   typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
     434             :   typedef mozilla::DisplayItemClip DisplayItemClip;
     435             :   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
     436             :   typedef mozilla::DisplayItemClipChainHasher DisplayItemClipChainHasher;
     437             :   typedef mozilla::DisplayItemClipChainEqualer DisplayItemClipChainEqualer;
     438             :   typedef mozilla::DisplayListClipState DisplayListClipState;
     439             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
     440             :   typedef nsIWidget::ThemeGeometry ThemeGeometry;
     441             :   typedef mozilla::layers::Layer Layer;
     442             :   typedef mozilla::layers::FrameMetrics FrameMetrics;
     443             :   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
     444             :   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
     445             :   typedef mozilla::Maybe<mozilla::layers::ScrollDirection> MaybeScrollDirection;
     446             : 
     447             :   /**
     448             :    * @param aReferenceFrame the frame at the root of the subtree; its origin
     449             :    * is the origin of the reference coordinate system for this display list
     450             :    * @param aMode encodes what the builder is being used for.
     451             :    * @param aBuildCaret whether or not we should include the caret in any
     452             :    * display lists that we make.
     453             :    */
     454             :   nsDisplayListBuilder(nsIFrame* aReferenceFrame,
     455             :                        nsDisplayListBuilderMode aMode,
     456             :                        bool aBuildCaret,
     457             :                        bool aRetainingDisplayList = false);
     458             :   ~nsDisplayListBuilder();
     459             : 
     460             :   void BeginFrame();
     461             :   void EndFrame();
     462             : 
     463             :   void AddTemporaryItem(nsDisplayItem* aItem)
     464             :   {
     465             :     mTemporaryItems.AppendElement(aItem);
     466             :   }
     467             : 
     468             :   void SetWillComputePluginGeometry(bool aWillComputePluginGeometry)
     469             :   {
     470             :     mWillComputePluginGeometry = aWillComputePluginGeometry;
     471             :   }
     472             :   void SetForPluginGeometry(bool aForPlugin)
     473             :   {
     474             :     if (aForPlugin) {
     475             :       NS_ASSERTION(mMode == nsDisplayListBuilderMode::PAINTING, "Can only switch from PAINTING to PLUGIN_GEOMETRY");
     476             :       NS_ASSERTION(mWillComputePluginGeometry, "Should have signalled this in advance");
     477             :       mMode = nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
     478             :     } else {
     479             :       NS_ASSERTION(mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY, "Can only switch from PAINTING to PLUGIN_GEOMETRY");
     480             :       mMode = nsDisplayListBuilderMode::PAINTING;
     481             :     }
     482             :   }
     483             : 
     484             :   mozilla::layers::LayerManager* GetWidgetLayerManager(nsView** aView = nullptr);
     485             : 
     486             :   /**
     487             :    * @return true if the display is being built in order to determine which
     488             :    * frame is under the mouse position.
     489             :    */
     490             :   bool IsForEventDelivery()
     491             :   {
     492             :     return mMode == nsDisplayListBuilderMode::EVENT_DELIVERY;
     493             :   }
     494             : 
     495             :   /**
     496             :    * Be careful with this. The display list will be built in PAINTING mode
     497             :    * first and then switched to PLUGIN_GEOMETRY before a second call to
     498             :    * ComputeVisibility.
     499             :    * @return true if the display list is being built to compute geometry
     500             :    * for plugins.
     501             :    */
     502             :   bool IsForPluginGeometry()
     503             :   {
     504             :     return mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY;
     505             :   }
     506             : 
     507             :   /**
     508             :    * @return true if the display list is being built for painting.
     509             :    */
     510             :   bool IsForPainting()
     511             :   {
     512             :     return mMode == nsDisplayListBuilderMode::PAINTING;
     513             :   }
     514             : 
     515             :   /**
     516             :    * @return true if the display list is being built for determining frame
     517             :    * visibility.
     518             :    */
     519             :   bool IsForFrameVisibility()
     520             :   {
     521             :     return mMode == nsDisplayListBuilderMode::FRAME_VISIBILITY;
     522             :   }
     523             : 
     524             :   /**
     525             :    * @return true if the display list is being built for creating the glyph
     526             :    * mask from text items.
     527             :    */
     528             :   bool IsForGenerateGlyphMask()
     529             :   {
     530             :     return mMode == nsDisplayListBuilderMode::GENERATE_GLYPH;
     531             :   }
     532             : 
     533             :   /**
     534             :    * @return true if the display list is being built for painting selection
     535             :    * background.
     536             :    */
     537             :   bool IsForPaintingSelectionBG()
     538             :   {
     539             :     return mMode == nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND;
     540             :   }
     541             : 
     542             :   bool BuildCompositorHitTestInfo()
     543             :   {
     544             :     return mBuildCompositorHitTestInfo;
     545             :   }
     546             : 
     547             :   bool WillComputePluginGeometry() { return mWillComputePluginGeometry; }
     548             :   /**
     549             :    * @return true if "painting is suppressed" during page load and we
     550             :    * should paint only the background of the document.
     551             :    */
     552             :   bool IsBackgroundOnly() {
     553             :     NS_ASSERTION(mPresShellStates.Length() > 0,
     554             :                  "don't call this if we're not in a presshell");
     555             :     return CurrentPresShellState()->mIsBackgroundOnly;
     556             :   }
     557             :   /**
     558             :    * @return true if the currently active BuildDisplayList call is being
     559             :    * applied to a frame at the root of a pseudo stacking context. A pseudo
     560             :    * stacking context is either a real stacking context or basically what
     561             :    * CSS2.1 appendix E refers to with "treat the element as if it created
     562             :    * a new stacking context
     563             :    */
     564             :   bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; }
     565             : 
     566             :   /**
     567             :    * @return the selection that painting should be restricted to (or nullptr
     568             :    * in the normal unrestricted case)
     569             :    */
     570             :   mozilla::dom::Selection* GetBoundingSelection() { return mBoundingSelection; }
     571             : 
     572             :   /**
     573             :    * @return the root of given frame's (sub)tree, whose origin
     574             :    * establishes the coordinate system for the child display items.
     575             :    */
     576             :   const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
     577             :                                         nsPoint* aOffset = nullptr) const;
     578             : 
     579             :   /**
     580             :    * @return the root of the display list's frame (sub)tree, whose origin
     581             :    * establishes the coordinate system for the display list
     582             :    */
     583             :   nsIFrame* RootReferenceFrame()
     584             :   {
     585             :     return mReferenceFrame;
     586             :   }
     587             : 
     588             :   /**
     589             :    * @return a point pt such that adding pt to a coordinate relative to aFrame
     590             :    * makes it relative to ReferenceFrame(), i.e., returns
     591           0 :    * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
     592             :    * the appunits of aFrame.
     593           0 :    */
     594           0 :   const nsPoint ToReferenceFrame(const nsIFrame* aFrame) const
     595           0 :   {
     596             :     nsPoint result;
     597             :     FindReferenceFrameFor(aFrame, &result);
     598             :     return result;
     599             :   }
     600             :   /**
     601             :    * When building the display list, the scrollframe aFrame will be "ignored"
     602             :    * for the purposes of clipping, and its scrollbars will be hidden. We use
     603             :    * this to allow RenderOffscreen to render a whole document without beign
     604             :    * clipped by the viewport or drawing the viewport scrollbars.
     605             :    */
     606             :   void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
     607             :   /**
     608             :    * Get the scrollframe to ignore, if any.
     609             :    */
     610             :   nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
     611             :   /**
     612             :    * Get the ViewID of the nearest scrolling ancestor frame.
     613             :    */
     614             :   ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
     615             :   /**
     616             :    * Get and set the flag that indicates if scroll parents should have layers
     617             :    * forcibly created. This flag is set when a deeply nested scrollframe has
     618             :    * a displayport, and for scroll handoff to work properly the ancestor
     619             :    * scrollframes should also get their own scrollable layers.
     620             :    */
     621             :   void ForceLayerForScrollParent() { mForceLayerForScrollParent = true; }
     622             :   /**
     623             :    * Get the ViewID and the scrollbar flags corresponding to the scrollbar for
     624             :    * which we are building display items at the moment.
     625             :    */
     626             :   ViewID GetCurrentScrollbarTarget() const { return mCurrentScrollbarTarget; }
     627             :   MaybeScrollDirection GetCurrentScrollbarDirection() const { return mCurrentScrollbarDirection; }
     628             :   /**
     629             :    * Returns true if building a scrollbar, and the scrollbar will not be
     630             :    * layerized.
     631             :    */
     632             :   bool IsBuildingNonLayerizedScrollbar() const {
     633             :     return mIsBuildingScrollbar && !mCurrentScrollbarWillHaveLayer;
     634             :   }
     635             :   /**
     636             :    * Calling this setter makes us include all out-of-flow descendant
     637             :    * frames in the display list, wherever they may be positioned (even
     638             :    * outside the dirty rects).
     639             :    */
     640             :   void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
     641             :   bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
     642             :   /**
     643             :    * Calling this setter makes us exclude all leaf frames that aren't
     644             :    * selected.
     645             :    */
     646             :   void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
     647             :   bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
     648             :   /**
     649             :    * Calling this setter makes us compute accurate visible regions at the cost
     650             :    * of performance if regions get very complex.
     651             :    */
     652             :   bool GetAccurateVisibleRegions() { return mMode == nsDisplayListBuilderMode::PLUGIN_GEOMETRY; }
     653             :   /**
     654             :    * @return Returns true if we should include the caret in any display lists
     655             :    * that we make.
     656             :    */
     657             :   bool IsBuildingCaret() const { return mBuildCaret; }
     658             : 
     659             :   bool IsRetainingDisplayList() const { return mRetainingDisplayList; }
     660             : 
     661             :   bool IsPartialUpdate() const { return mPartialUpdate; }
     662             :   void SetPartialUpdate(bool aPartial) { mPartialUpdate = aPartial; }
     663             : 
     664             :   bool IsBuilding() const { return mIsBuilding; }
     665             :   void SetIsBuilding(bool aIsBuilding)
     666             :   {
     667             :     mIsBuilding = aIsBuilding;
     668             :     for (nsIFrame* f : mModifiedFramesDuringBuilding) {
     669             :       f->SetFrameIsModified(false);
     670             :     }
     671             :     mModifiedFramesDuringBuilding.Clear();
     672             :   }
     673             : 
     674             :   bool InInvalidSubtree() const { return mInInvalidSubtree; }
     675             : 
     676             :   /**
     677             :    * Allows callers to selectively override the regular paint suppression checks,
     678             :    * so that methods like GetFrameForPoint work when painting is suppressed.
     679             :    */
     680             :   void IgnorePaintSuppression() { mIgnoreSuppression = true; }
     681             :   /**
     682             :    * @return Returns if this builder will ignore paint suppression.
     683             :    */
     684             :   bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
     685             :   /**
     686             :    * Call this if we're doing normal painting to the window.
     687             :    */
     688             :   void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
     689             :   bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
     690             :   /**
     691             :    * Call this to prevent descending into subdocuments.
     692             :    */
     693             :   void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
     694             :   bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
     695             : 
     696             :   /**
     697             :    * Get dirty rect relative to current frame (the frame that we're calling
     698             :    * BuildDisplayList on right now).
     699             :    */
     700             :   const nsRect& GetVisibleRect() { return mVisibleRect; }
     701             :   const nsRect& GetDirtyRect() { return mDirtyRect; }
     702             : 
     703             :   void SetVisibleRect(const nsRect& aVisibleRect) { mVisibleRect = aVisibleRect; }
     704             :   void IntersectVisibleRect(const nsRect& aVisibleRect) { mVisibleRect.IntersectRect(mVisibleRect, aVisibleRect); }
     705             :   void SetDirtyRect(const nsRect& aDirtyRect) { mDirtyRect = aDirtyRect; }
     706             :   void IntersectDirtyRect(const nsRect& aDirtyRect) { mDirtyRect.IntersectRect(mDirtyRect, aDirtyRect); }
     707             : 
     708             :   const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
     709             :   const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
     710             :   const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
     711             :   AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() {
     712             :     return mCurrentAGR;
     713             :   }
     714             :   AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() {
     715             :     return mRootAGR;
     716             :   }
     717             : 
     718             :   void RecomputeCurrentAnimatedGeometryRoot();
     719             : 
     720             :   void Check() {
     721             :     mPool.Check();
     722             :   }
     723             : 
     724             :   /**
     725             :    * Returns true if merging and flattening of display lists should be
     726             :    * performed while computing visibility.
     727             :    */
     728             :   bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
     729             :   void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; }
     730             : 
     731             :   /**
     732             :    * Sets the current compositor hit test info to |aHitTestInfo|.
     733             :    * This is used during display list building to determine if the parent frame
     734             :    * hit test info contains the same information that child frame needs.
     735             :    */
     736             :   void SetCompositorHitTestInfo(nsDisplayCompositorHitTestInfo* aHitTestInfo)
     737             :   {
     738             :     mCompositorHitTestInfo = aHitTestInfo;
     739             :   }
     740             :   nsDisplayCompositorHitTestInfo* GetCompositorHitTestInfo() const
     741             :   {
     742             :     return mCompositorHitTestInfo;
     743             :   }
     744             : 
     745             :   /**
     746             :    * Builds a new nsDisplayCompositorHitTestInfo for the frame |aFrame| if
     747           0 :    * needed, and adds it to the top of |aList|. If |aBuildNew| is true, the
     748             :    * previous hit test info will not be reused.
     749           0 :    */
     750             :   void BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
     751             :                                           nsDisplayList* aList,
     752             :                                           const bool aBuildNew);
     753             : 
     754             :   bool IsInsidePointerEventsNoneDoc()
     755             :   {
     756             :     return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
     757             :   }
     758             : 
     759             :   bool GetAncestorHasApzAwareEventHandler() const { return mAncestorHasApzAwareEventHandler; }
     760             :   void SetAncestorHasApzAwareEventHandler(bool aValue)
     761             :   {
     762             :     mAncestorHasApzAwareEventHandler = aValue;
     763             :   }
     764             : 
     765             :   bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
     766             :   void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
     767             :   void ClearHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = false; }
     768             : 
     769             :   bool SetIsCompositingCheap(bool aCompositingCheap) {
     770             :     bool temp = mIsCompositingCheap;
     771             :     mIsCompositingCheap = aCompositingCheap;
     772             :     return temp;
     773             :   }
     774             :   bool IsCompositingCheap() const { return mIsCompositingCheap; }
     775             :   /**
     776             :    * Display the caret if needed.
     777             :    */
     778             :   bool DisplayCaret(nsIFrame* aFrame, nsDisplayList* aList)
     779             :   {
     780             :     nsIFrame* frame = GetCaretFrame();
     781             :     if (aFrame == frame) {
     782             :       frame->DisplayCaret(this, aList);
     783             :       return true;
     784             :     }
     785             :     return false;
     786             :   }
     787             :   /**
     788             :    * Get the frame that the caret is supposed to draw in.
     789             :    * If the caret is currently invisible, this will be null.
     790             :    */
     791             :   nsIFrame* GetCaretFrame() {
     792             :     return CurrentPresShellState()->mCaretFrame;
     793             :   }
     794             :   /**
     795             :    * Get the rectangle we're supposed to draw the caret into.
     796             :    */
     797             :   const nsRect& GetCaretRect() {
     798             :     return CurrentPresShellState()->mCaretRect;
     799             :   }
     800             :   /**
     801             :    * Get the caret associated with the current presshell.
     802             :    */
     803             :   nsCaret* GetCaret();
     804             :   /**
     805             :    * Notify the display list builder that we're entering a presshell.
     806             :    * aReferenceFrame should be a frame in the new presshell.
     807             :    * aPointerEventsNoneDoc should be set to true if the frame generating this
     808             :    * document is pointer-events:none.
     809             :    */
     810             :   void EnterPresShell(nsIFrame* aReferenceFrame,
     811             :                       bool aPointerEventsNoneDoc = false);
     812             :   /**
     813             :    * For print-preview documents, we sometimes need to build display items for
     814             :    * the same frames multiple times in the same presentation, with different
     815             :    * clipping. Between each such batch of items, call
     816             :    * ResetMarkedFramesForDisplayList to make sure that the results of
     817             :    * MarkFramesForDisplayList do not carry over between batches.
     818             :    */
     819             :   void ResetMarkedFramesForDisplayList(nsIFrame* aReferenceFrame);
     820             :   /**
     821             :    * Notify the display list builder that we're leaving a presshell.
     822             :    */
     823             :   void LeavePresShell(nsIFrame* aReferenceFrame, nsDisplayList* aPaintedContents);
     824             : 
     825             :   void IncrementPresShellPaintCount(nsIPresShell* aPresShell);
     826             : 
     827             :   /**
     828             :    * Returns true if we're currently building a display list that's
     829             :    * directly or indirectly under an nsDisplayTransform.
     830             :    */
     831             :   bool IsInTransform() const { return mInTransform; }
     832             :   /**
     833             :    * Indicate whether or not we're directly or indirectly under and
     834             :    * nsDisplayTransform or SVG foreignObject.
     835             :    */
     836             :   void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
     837             : 
     838             :   bool IsInPageSequence() const { return mInPageSequence; }
     839             :   void SetInPageSequence(bool aInPage) { mInPageSequence = aInPage; }
     840             : 
     841             :   /**
     842             :    * Return true if we're currently building a display list for a
     843             :    * nested presshell.
     844             :    */
     845             :   bool IsInSubdocument() { return mPresShellStates.Length() > 1; }
     846             : 
     847             :   void SetDisablePartialUpdates(bool aDisable) { mDisablePartialUpdates = aDisable; }
     848             :   bool DisablePartialUpdates() { return mDisablePartialUpdates; }
     849             : 
     850             :   void SetPartialBuildFailed(bool aFailed) { mPartialBuildFailed = aFailed; }
     851             :   bool PartialBuildFailed() { return mPartialBuildFailed; }
     852             : 
     853             :   /**
     854             :    * Return true if we're currently building a display list for the presshell
     855             :    * of a chrome document, or if we're building the display list for a popup.
     856             :    */
     857             :   bool IsInChromeDocumentOrPopup() {
     858             :     return mIsInChromePresContext || mIsBuildingForPopup;
     859             :   }
     860             : 
     861             :   /**
     862             :    * @return true if images have been set to decode synchronously.
     863             :    */
     864             :   bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
     865             : 
     866             :   /**
     867             :    * Indicates whether we should synchronously decode images. If true, we decode
     868             :    * and draw whatever image data has been loaded. If false, we just draw
     869             :    * whatever has already been decoded.
     870             :    */
     871             :   void SetSyncDecodeImages(bool aSyncDecodeImages) {
     872             :     mSyncDecodeImages = aSyncDecodeImages;
     873             :   }
     874             : 
     875             :   void FreeClipChains();
     876             : 
     877             :   /*
     878             :    * Frees the temporary display items created during merging.
     879             :    */
     880             :   void FreeTemporaryItems();
     881             : 
     882             :   /**
     883             :    * Helper method to generate background painting flags based on the
     884             :    * information available in the display list builder. Currently only
     885             :    * accounts for mSyncDecodeImages.
     886             :    */
     887             :   uint32_t GetBackgroundPaintFlags();
     888             : 
     889             :   /**
     890             :    * Subtracts aRegion from *aVisibleRegion. We avoid letting
     891             :    * aVisibleRegion become overcomplex by simplifying it if necessary.
     892             :    */
     893             :   void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
     894             :                                  const nsRegion& aRegion);
     895             : 
     896             :   /**
     897             :    * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
     898             :    * (which is relative to aDirtyFrame). If the frames have placeholders
     899             :    * that might not be displayed, we mark the placeholders and their ancestors
     900             :    * to ensure that display list construction descends into them
     901             :    * anyway. nsDisplayListBuilder will take care of unmarking them when it is
     902             :    * destroyed.
     903             :    */
     904             :   void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
     905             :                                 const nsFrameList& aFrames);
     906             :   void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
     907             :   void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
     908             :   void AddFrameMarkedForDisplayIfVisible(nsIFrame* aFrame);
     909             : 
     910             :   void ClearFixedBackgroundDisplayData();
     911             :   /**
     912             :    * Mark all child frames that Preserve3D() as needing display.
     913             :    * Because these frames include transforms set on their parent, dirty rects
     914             :    * for intermediate frames may be empty, yet child frames could still be visible.
     915             :    */
     916             :   void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame);
     917             : 
     918             :   /**
     919             :    * Returns true if we need to descend into this frame when building
     920             :    * the display list, even though it doesn't intersect the dirty
     921             :    * rect, because it may have out-of-flows that do so.
     922             :    */
     923             :   bool ShouldDescendIntoFrame(nsIFrame* aFrame, bool aVisible) const {
     924             :     return
     925             :       (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
     926             :       (aVisible && aFrame->ForceDescendIntoIfVisible()) ||
     927             :       GetIncludeAllOutOfFlows();
     928             :   }
     929             : 
     930             :   /**
     931             :    * Returns the list of registered theme geometries.
     932             :    */
     933             :   nsTArray<ThemeGeometry> GetThemeGeometries() const
     934             :   {
     935             :     nsTArray<ThemeGeometry> geometries;
     936             : 
     937             :     for (auto iter = mThemeGeometries.ConstIter(); !iter.Done(); iter.Next()) {
     938             :       geometries.AppendElements(*iter.Data());
     939             :     }
     940             : 
     941             :     return geometries;
     942             :   }
     943             : 
     944             :   /**
     945             :    * Notifies the builder that a particular themed widget exists
     946             :    * at the given rectangle within the currently built display list.
     947             :    * For certain appearance values (currently only NS_THEME_TOOLBAR and
     948             :    * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
     949             :    * construction, for every themed widget of the right type within the
     950             :    * display list, except for themed widgets which are transformed or have
     951             :    * effects applied to them (e.g. CSS opacity or filters).
     952             :    *
     953             :    * @param aWidgetType the -moz-appearance value for the themed widget
     954             :    * @param aItem the item associated with the theme geometry
     955             :    * @param aRect the device-pixel rect relative to the widget's displayRoot
     956             :    * for the themed widget
     957             :    */
     958             :   void RegisterThemeGeometry(uint8_t aWidgetType, nsDisplayItem* aItem,
     959             :                              const mozilla::LayoutDeviceIntRect& aRect)
     960             :   {
     961             :     if (!mIsPaintingToWindow) {
     962             :       return;
     963             :     }
     964             : 
     965           0 :     nsTArray<ThemeGeometry>* geometries = mThemeGeometries.LookupOrAdd(aItem);
     966             :     geometries->AppendElement(ThemeGeometry(aWidgetType, aRect));
     967           0 :   }
     968           0 : 
     969             :   /**
     970             :    * Removes theme geometries associated with the given display item |aItem|.
     971             :    */
     972             :   void UnregisterThemeGeometry(nsDisplayItem* aItem)
     973             :   {
     974             :     mThemeGeometries.Remove(aItem);
     975             :   }
     976             : 
     977             :   /**
     978             :    * Adjusts mWindowDraggingRegion to take into account aFrame. If aFrame's
     979             :    * -moz-window-dragging value is |drag|, its border box is added to the
     980             :    * collected dragging region; if the value is |no-drag|, the border box is
     981             :    * subtracted from the region; if the value is |default|, that frame does
     982             :    * not influence the window dragging region.
     983             :    */
     984             :   void AdjustWindowDraggingRegion(nsIFrame* aFrame);
     985             : 
     986             :   LayoutDeviceIntRegion GetWindowDraggingRegion() const;
     987             : 
     988             :   void RemoveModifiedWindowRegions();
     989             :   void ClearRetainedWindowRegions();
     990             : 
     991             :   /**
     992             :    * Allocate memory in our arena. It will only be freed when this display list
     993             :    * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
     994             :    * destructors are called as soon as the item is no longer used.
     995             :    */
     996             :   void* Allocate(size_t aSize, DisplayItemType aType);
     997             : 
     998             :   void Destroy(DisplayItemType aType, void* aPtr);
     999             : 
    1000             :   /**
    1001             :    * Allocate a new ActiveScrolledRoot in the arena. Will be cleaned up
    1002             :    * automatically when the arena goes away.
    1003             :    */
    1004             :   ActiveScrolledRoot* AllocateActiveScrolledRoot(const ActiveScrolledRoot* aParent,
    1005             :                                                  nsIScrollableFrame* aScrollableFrame);
    1006             : 
    1007             :   /**
    1008             :    * Allocate a new DisplayItemClipChain object in the arena. Will be cleaned
    1009             :    * up automatically when the arena goes away.
    1010             :    */
    1011             :   const DisplayItemClipChain* AllocateDisplayItemClipChain(const DisplayItemClip& aClip,
    1012             :                                                            const ActiveScrolledRoot* aASR,
    1013             :                                                            const DisplayItemClipChain* aParent);
    1014             : 
    1015             :   /**
    1016             :    * Intersect two clip chains, allocating the new clip chain items in this
    1017             :    * builder's arena. The result is parented to aAncestor, and no intersections
    1018             :    * happen past aAncestor's ASR.
    1019             :    * That means aAncestor has to be living in this builder's arena already.
    1020             :    * aLeafClip1 and aLeafClip2 only need to outlive the call to this function,
    1021             :    * their values are copied into the newly-allocated intersected clip chain
    1022             :    * and this function does not hold on to any pointers to them.
    1023             :    */
    1024             :   const DisplayItemClipChain* CreateClipChainIntersection(const DisplayItemClipChain* aAncestor,
    1025             :                                                           const DisplayItemClipChain* aLeafClip1,
    1026             :                                                           const DisplayItemClipChain* aLeafClip2);
    1027             : 
    1028             :   /**
    1029             :    * Clone the supplied clip chain's chain items into this builder's arena.
    1030             :    */
    1031             :   const DisplayItemClipChain* CopyWholeChain(const DisplayItemClipChain* aClipChain);
    1032             : 
    1033             :   /**
    1034             :    * Only used for containerful root scrolling. This is a workaround.
    1035             :    */
    1036             :   void SetActiveScrolledRootForRootScrollframe(const ActiveScrolledRoot* aASR)
    1037             :   { mActiveScrolledRootForRootScrollframe = aASR; }
    1038             :   const ActiveScrolledRoot* ActiveScrolledRootForRootScrollframe() const
    1039             :   { return mActiveScrolledRootForRootScrollframe; }
    1040             : 
    1041             :   /**
    1042             :    * Transfer off main thread animations to the layer.  May be called
    1043             :    * with aBuilder and aItem both null, but only if the caller has
    1044             :    * already checked that off main thread animations should be sent to
    1045             :    * the layer.  When they are both null, the animations are added to
    1046             :    * the layer as pending animations.
    1047             :    */
    1048             :   static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
    1049             :                                                  nsDisplayListBuilder* aBuilder,
    1050             :                                                  nsDisplayItem* aItem,
    1051             :                                                  nsIFrame* aFrame,
    1052             :                                                  nsCSSPropertyID aProperty);
    1053             : 
    1054             :   /**
    1055             :    * Merges the display items in |aMergedItems| and returns a new temporary
    1056             :    * display item.
    1057             :    * The display items in |aMergedItems| have to be mergeable with each other.
    1058             :    */
    1059             :   nsDisplayItem* MergeItems(nsTArray<nsDisplayItem*>& aMergedItems);
    1060             : 
    1061             :   /**
    1062             :    * A helper class to temporarily set the value of
    1063             :    * mIsAtRootOfPseudoStackingContext, and temporarily
    1064             :    * set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
    1065             :    * aDirtyRect is relative to aForChild.
    1066             :    */
    1067             :   class AutoBuildingDisplayList {
    1068             :   public:
    1069             :     AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
    1070             :                             nsIFrame* aForChild,
    1071             :                             const nsRect& aVisibleRect,
    1072             :                             const nsRect& aDirtyRect,
    1073             :                             bool aIsRoot)
    1074             :       : mBuilder(aBuilder),
    1075             :         mPrevFrame(aBuilder->mCurrentFrame),
    1076             :         mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
    1077             :         mPrevCompositorHitTestInfo(aBuilder->mCompositorHitTestInfo),
    1078             :         mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
    1079             :         mPrevVisibleRect(aBuilder->mVisibleRect),
    1080             :         mPrevDirtyRect(aBuilder->mDirtyRect),
    1081             :         mPrevAGR(aBuilder->mCurrentAGR),
    1082             :         mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
    1083             :         mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler),
    1084             :         mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems),
    1085             :         mPrevInInvalidSubtree(aBuilder->mInInvalidSubtree)
    1086             :     {
    1087             :       if (aForChild->IsTransformed()) {
    1088             :         aBuilder->mCurrentOffsetToReferenceFrame = nsPoint();
    1089             :         aBuilder->mCurrentReferenceFrame = aForChild;
    1090             :       } else if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
    1091             :         aBuilder->mCurrentOffsetToReferenceFrame += aForChild->GetPosition();
    1092             :       } else {
    1093             :         aBuilder->mCurrentReferenceFrame =
    1094             :           aBuilder->FindReferenceFrameFor(aForChild,
    1095             :               &aBuilder->mCurrentOffsetToReferenceFrame);
    1096             :       }
    1097             :       bool isAsync;
    1098             :       mCurrentAGRState = aBuilder->IsAnimatedGeometryRoot(aForChild, isAsync);
    1099             :       if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
    1100             :         if (mCurrentAGRState == AGR_YES) {
    1101             :           aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(aForChild, isAsync, aBuilder->mCurrentAGR);
    1102             :         }
    1103             :       } else if (aForChild != aBuilder->mCurrentFrame) {
    1104             :         aBuilder->mCurrentAGR = aBuilder->FindAnimatedGeometryRootFor(aForChild);
    1105             :       }
    1106             :       MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
    1107             :       aBuilder->mInInvalidSubtree = aBuilder->mInInvalidSubtree || aForChild->IsFrameModified();
    1108             :       aBuilder->mCurrentFrame = aForChild;
    1109             :       aBuilder->mVisibleRect = aVisibleRect;
    1110             :       aBuilder->mDirtyRect = aBuilder->mInInvalidSubtree ? aVisibleRect : aDirtyRect;
    1111             :       aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
    1112             :     }
    1113             :     void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) {
    1114             :       mBuilder->mCurrentReferenceFrame = aFrame;
    1115             :       mBuilder->mCurrentOffsetToReferenceFrame = aOffset;
    1116             :     }
    1117             :     bool IsAnimatedGeometryRoot() const {
    1118             :       return mCurrentAGRState == AGR_YES;
    1119             :     }
    1120             :     bool MaybeAnimatedGeometryRoot() const {
    1121             :       return mCurrentAGRState == AGR_MAYBE;
    1122             :     }
    1123             :     void RestoreBuildingInvisibleItemsValue() {
    1124             :       mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
    1125             :     }
    1126             :     ~AutoBuildingDisplayList() {
    1127             :       mBuilder->mCurrentFrame = mPrevFrame;
    1128             :       mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
    1129             :       mBuilder->mCompositorHitTestInfo = mPrevCompositorHitTestInfo;
    1130             :       mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
    1131             :       mBuilder->mVisibleRect = mPrevVisibleRect;
    1132             :       mBuilder->mDirtyRect = mPrevDirtyRect;
    1133             :       mBuilder->mCurrentAGR = mPrevAGR;
    1134             :       mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
    1135             :       mBuilder->mAncestorHasApzAwareEventHandler = mPrevAncestorHasApzAwareEventHandler;
    1136             :       mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
    1137             :       mBuilder->mInInvalidSubtree = mPrevInInvalidSubtree;
    1138             :     }
    1139             :   private:
    1140             :     nsDisplayListBuilder* mBuilder;
    1141             :     AGRState              mCurrentAGRState;
    1142             :     const nsIFrame*       mPrevFrame;
    1143             :     const nsIFrame*       mPrevReferenceFrame;
    1144             :     nsDisplayCompositorHitTestInfo* mPrevCompositorHitTestInfo;
    1145             :     nsPoint               mPrevOffset;
    1146             :     nsRect                mPrevVisibleRect;
    1147             :     nsRect                mPrevDirtyRect;
    1148             :     RefPtr<AnimatedGeometryRoot> mPrevAGR;
    1149             :     bool                  mPrevIsAtRootOfPseudoStackingContext;
    1150             :     bool                  mPrevAncestorHasApzAwareEventHandler;
    1151             :     bool                  mPrevBuildingInvisibleItems;
    1152             :     bool                  mPrevInInvalidSubtree;
    1153             :   };
    1154             : 
    1155             :   /**
    1156             :    * A helper class to temporarily set the value of mInTransform.
    1157             :    */
    1158             :   class AutoInTransformSetter {
    1159             :   public:
    1160             :     AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
    1161             :       : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
    1162             :       aBuilder->mInTransform = aInTransform;
    1163             :     }
    1164             :     ~AutoInTransformSetter() {
    1165             :       mBuilder->mInTransform = mOldValue;
    1166             :     }
    1167             :   private:
    1168             :     nsDisplayListBuilder* mBuilder;
    1169             :     bool                  mOldValue;
    1170             :   };
    1171             : 
    1172             :   /**
    1173             :    * A helper class to temporarily set the value of mFilterASR.
    1174             :    */
    1175             :   class AutoFilterASRSetter {
    1176             :   public:
    1177             :     AutoFilterASRSetter(nsDisplayListBuilder* aBuilder, bool aUsingFilter)
    1178             :       : mBuilder(aBuilder), mOldValue(aBuilder->mFilterASR)
    1179             :     {
    1180             :       if (!aBuilder->mFilterASR && aUsingFilter) {
    1181             :         aBuilder->mFilterASR = aBuilder->CurrentActiveScrolledRoot();
    1182             :       }
    1183             :     }
    1184             :     ~AutoFilterASRSetter() {
    1185             :       mBuilder->mFilterASR = mOldValue;
    1186             :     }
    1187             :   private:
    1188             :     nsDisplayListBuilder* mBuilder;
    1189             :     const ActiveScrolledRoot* mOldValue;
    1190             :   };
    1191             : 
    1192             :   /**
    1193             :    * A helper class to temporarily set the value of mCurrentScrollParentId.
    1194             :    */
    1195             :   class AutoCurrentScrollParentIdSetter {
    1196             :   public:
    1197             :     AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId)
    1198             :       : mBuilder(aBuilder)
    1199             :       , mOldValue(aBuilder->mCurrentScrollParentId)
    1200             :       , mOldForceLayer(aBuilder->mForceLayerForScrollParent) {
    1201             :       // If this AutoCurrentScrollParentIdSetter has the same scrollId as the
    1202             :       // previous one on the stack, then that means the scrollframe that
    1203             :       // created this isn't actually scrollable and cannot participate in
    1204             :       // scroll handoff. We set mCanBeScrollParent to false to indicate this.
    1205             :       mCanBeScrollParent = (mOldValue != aScrollId);
    1206             :       aBuilder->mCurrentScrollParentId = aScrollId;
    1207             :       aBuilder->mForceLayerForScrollParent = false;
    1208             :     }
    1209             :     bool ShouldForceLayerForScrollParent() const {
    1210             :       // Only scrollframes participating in scroll handoff can be forced to
    1211             :       // layerize
    1212             :       return mCanBeScrollParent && mBuilder->mForceLayerForScrollParent;
    1213             :     };
    1214             :     ~AutoCurrentScrollParentIdSetter() {
    1215             :       mBuilder->mCurrentScrollParentId = mOldValue;
    1216             :       if (mCanBeScrollParent) {
    1217             :         // If this flag is set, caller code is responsible for having dealt
    1218             :         // with the current value of mBuilder->mForceLayerForScrollParent, so
    1219             :         // we can just restore the old value.
    1220             :         mBuilder->mForceLayerForScrollParent = mOldForceLayer;
    1221             :       } else {
    1222             :         // Otherwise we need to keep propagating the force-layerization flag
    1223             :         // upwards to the next ancestor scrollframe that does participate in
    1224             :         // scroll handoff.
    1225             :         mBuilder->mForceLayerForScrollParent |= mOldForceLayer;
    1226             :       }
    1227             :     }
    1228             :   private:
    1229             :     nsDisplayListBuilder* mBuilder;
    1230             :     ViewID                mOldValue;
    1231             :     bool                  mOldForceLayer;
    1232             :     bool                  mCanBeScrollParent;
    1233             :   };
    1234             : 
    1235             :   /**
    1236             :    * Used to update the current active scrolled root on the display list
    1237             :    * builder, and to create new active scrolled roots.
    1238             :    */
    1239             :   class AutoCurrentActiveScrolledRootSetter {
    1240             :   public:
    1241             :     explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
    1242             :       : mBuilder(aBuilder)
    1243             :       , mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot)
    1244             :       , mContentClipASR(aBuilder->ClipState().GetContentClipASR())
    1245             :       , mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length())
    1246             :       , mUsed(false)
    1247             :     {
    1248             :     }
    1249             : 
    1250             :     ~AutoCurrentActiveScrolledRootSetter()
    1251             :     {
    1252             :       mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
    1253             :     }
    1254             : 
    1255             :     void SetCurrentActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot);
    1256             : 
    1257             :     void EnterScrollFrame(nsIScrollableFrame* aScrollableFrame)
    1258             :     {
    1259             :       MOZ_ASSERT(!mUsed);
    1260             :       ActiveScrolledRoot* asr = mBuilder->AllocateActiveScrolledRoot(
    1261             :         mBuilder->mCurrentActiveScrolledRoot, aScrollableFrame);
    1262             :       mBuilder->mCurrentActiveScrolledRoot = asr;
    1263             :       mUsed = true;
    1264             :     }
    1265             : 
    1266             :     void InsertScrollFrame(nsIScrollableFrame* aScrollableFrame);
    1267             : 
    1268             :   private:
    1269             :     nsDisplayListBuilder* mBuilder;
    1270             :     /**
    1271             :      * The builder's mCurrentActiveScrolledRoot at construction time which
    1272             :      * needs to be restored at destruction time.
    1273             :      */
    1274             :     const ActiveScrolledRoot* mSavedActiveScrolledRoot;
    1275             :     /**
    1276             :      * If there's a content clip on the builder at construction time, then
    1277             :      * mContentClipASR is that content clip's ASR, otherwise null. The
    1278             :      * assumption is that the content clip doesn't get relaxed while this
    1279             :      * object is on the stack.
    1280             :      */
    1281             :     const ActiveScrolledRoot* mContentClipASR;
    1282             :     /**
    1283             :      * InsertScrollFrame needs to mutate existing ASRs (those that were
    1284             :      * created while this object was on the stack), and mDescendantsStartIndex
    1285             :      * makes it easier to skip ASRs that were created in the past.
    1286             :      */
    1287             :     size_t mDescendantsStartIndex;
    1288             :     /**
    1289             :      * Flag to make sure that only one of SetCurrentActiveScrolledRoot /
    1290             :      * EnterScrollFrame / InsertScrollFrame is called per instance of this
    1291             :      * class.
    1292             :      */
    1293             :     bool mUsed;
    1294             :   };
    1295             : 
    1296             :   /**
    1297             :    * Keeps track of the innermost ASR that can be used as the ASR for a
    1298             :    * container item that wraps all items that were created while this
    1299             :    * object was on the stack.
    1300             :    * The rule is: all child items of the container item need to have
    1301             :    * clipped bounds with respect to the container ASR.
    1302             :    */
    1303             :   class AutoContainerASRTracker {
    1304             :   public:
    1305             :     explicit AutoContainerASRTracker(nsDisplayListBuilder* aBuilder)
    1306             :       : mBuilder(aBuilder)
    1307             :       , mSavedContainerASR(aBuilder->mCurrentContainerASR)
    1308             :     {
    1309             :       mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickDescendant(
    1310             :         mBuilder->ClipState().GetContentClipASR(),
    1311             :         mBuilder->mCurrentActiveScrolledRoot);
    1312             :     }
    1313             : 
    1314             :     const ActiveScrolledRoot* GetContainerASR()
    1315             :     {
    1316             :       return mBuilder->mCurrentContainerASR;
    1317             :     }
    1318             : 
    1319             :     ~AutoContainerASRTracker()
    1320             :     {
    1321             :       mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
    1322             :         mBuilder->mCurrentContainerASR, mSavedContainerASR);
    1323             :     }
    1324             : 
    1325             :   private:
    1326             :     nsDisplayListBuilder* mBuilder;
    1327             :     const ActiveScrolledRoot* mSavedContainerASR;
    1328             :   };
    1329             : 
    1330             :   /**
    1331             :    * A helper class to temporarily set the value of mCurrentScrollbarTarget
    1332             :    * and mCurrentScrollbarFlags.
    1333             :    */
    1334             :   class AutoCurrentScrollbarInfoSetter {
    1335             :   public:
    1336             :     AutoCurrentScrollbarInfoSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollTargetID,
    1337             :                                    const MaybeScrollDirection& aScrollbarDirection, bool aWillHaveLayer)
    1338             :      : mBuilder(aBuilder) {
    1339             :       aBuilder->mIsBuildingScrollbar = true;
    1340             :       aBuilder->mCurrentScrollbarTarget = aScrollTargetID;
    1341             :       aBuilder->mCurrentScrollbarDirection = aScrollbarDirection;
    1342             :       aBuilder->mCurrentScrollbarWillHaveLayer = aWillHaveLayer;
    1343             :     }
    1344             :     ~AutoCurrentScrollbarInfoSetter() {
    1345             :       // No need to restore old values because scrollbars cannot be nested.
    1346             :       mBuilder->mIsBuildingScrollbar = false;
    1347             :       mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
    1348             :       mBuilder->mCurrentScrollbarDirection.reset();
    1349             :       mBuilder->mCurrentScrollbarWillHaveLayer = false;
    1350             :     }
    1351             :   private:
    1352             :     nsDisplayListBuilder* mBuilder;
    1353             :   };
    1354             : 
    1355             :   /**
    1356             :    * A helper class to track current effective transform for items.
    1357             :    *
    1358             :    * For frames that is Combines3DTransformWithAncestors(), we need to
    1359             :    * apply all transforms of ancestors on the same preserves3D chain
    1360             :    * on the bounds of current frame to the coordination of the 3D
    1361           0 :    * context root.  The 3D context root computes it's bounds from
    1362           0 :    * these transformed bounds.
    1363           0 :    */
    1364             :   class AutoAccumulateTransform {
    1365           0 :   public:
    1366           0 :     typedef mozilla::gfx::Matrix4x4 Matrix4x4;
    1367           0 : 
    1368             :     explicit AutoAccumulateTransform(nsDisplayListBuilder* aBuilder)
    1369             :       : mBuilder(aBuilder)
    1370             :       , mSavedTransform(aBuilder->mPreserves3DCtx.mAccumulatedTransform) {}
    1371             : 
    1372             :     ~AutoAccumulateTransform() {
    1373             :       mBuilder->mPreserves3DCtx.mAccumulatedTransform = mSavedTransform;
    1374             :     }
    1375             : 
    1376             :     void Accumulate(const Matrix4x4& aTransform) {
    1377             :       mBuilder->mPreserves3DCtx.mAccumulatedTransform =
    1378           0 :         aTransform * mBuilder->mPreserves3DCtx.mAccumulatedTransform;
    1379           0 :     }
    1380           0 : 
    1381             :     const Matrix4x4& GetCurrentTransform() {
    1382             :       return mBuilder->mPreserves3DCtx.mAccumulatedTransform;
    1383             :     }
    1384             : 
    1385             :     void StartRoot() {
    1386             :       mBuilder->mPreserves3DCtx.mAccumulatedTransform = Matrix4x4();
    1387             :     }
    1388             : 
    1389             :   private:
    1390             :     nsDisplayListBuilder* mBuilder;
    1391             :     Matrix4x4 mSavedTransform;
    1392             :   };
    1393             : 
    1394             :   /**
    1395             :    * A helper class to collect bounds rects of descendants.
    1396             :    *
    1397             :    * For a 3D context root, it's bounds is computed from the bounds of
    1398           0 :    * descendants.  If we transform bounds frame by frame applying
    1399           0 :    * transforms, the bounds may turn to empty for any singular
    1400           0 :    * transform on the path, but it is not empty for the accumulated
    1401           0 :    * transform.
    1402           0 :    */
    1403           0 :   class AutoAccumulateRect {
    1404           0 :   public:
    1405           0 :     explicit AutoAccumulateRect(nsDisplayListBuilder* aBuilder)
    1406           0 :       : mBuilder(aBuilder)
    1407           0 :       , mSavedRect(aBuilder->mPreserves3DCtx.mAccumulatedRect) {
    1408             :       aBuilder->mPreserves3DCtx.mAccumulatedRect = nsRect();
    1409             :       aBuilder->mPreserves3DCtx.mAccumulatedRectLevels++;
    1410             :     }
    1411             :     ~AutoAccumulateRect() {
    1412             :       mBuilder->mPreserves3DCtx.mAccumulatedRect = mSavedRect;
    1413             :       mBuilder->mPreserves3DCtx.mAccumulatedRectLevels--;
    1414             :     }
    1415             : 
    1416             :   private:
    1417             :     nsDisplayListBuilder* mBuilder;
    1418             :     nsRect mSavedRect;
    1419             :   };
    1420             : 
    1421             :   void AccumulateRect(const nsRect& aRect) {
    1422             :     mPreserves3DCtx.mAccumulatedRect.UnionRect(mPreserves3DCtx.mAccumulatedRect, aRect);
    1423             :   }
    1424             :   const nsRect& GetAccumulatedRect() {
    1425             :     return mPreserves3DCtx.mAccumulatedRect;
    1426             :   }
    1427             :   /**
    1428             :    * The level is increased by one for items establishing 3D rendering
    1429             :    * context and starting a new accumulation.
    1430             :    */
    1431             :   int GetAccumulatedRectLevels() {
    1432             :     return mPreserves3DCtx.mAccumulatedRectLevels;
    1433             :   }
    1434             : 
    1435             :   // Helpers for tables
    1436             :   nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
    1437             :   void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
    1438             : 
    1439             :   struct OutOfFlowDisplayData {
    1440             :     OutOfFlowDisplayData(const DisplayItemClipChain* aContainingBlockClipChain,
    1441             :                          const DisplayItemClipChain* aCombinedClipChain,
    1442             :                          const ActiveScrolledRoot* aContainingBlockActiveScrolledRoot,
    1443             :                          const nsRect &aVisibleRect,
    1444             :                          const nsRect &aDirtyRect)
    1445             :       : mContainingBlockClipChain(aContainingBlockClipChain)
    1446             :       , mCombinedClipChain(aCombinedClipChain)
    1447             :       , mContainingBlockActiveScrolledRoot(aContainingBlockActiveScrolledRoot)
    1448             :       , mVisibleRect(aVisibleRect)
    1449             :       , mDirtyRect(aDirtyRect)
    1450             :     {}
    1451             :     const DisplayItemClipChain* mContainingBlockClipChain;
    1452             :     const DisplayItemClipChain* mCombinedClipChain; // only necessary for the special case of top layer
    1453             :     const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
    1454             :     nsRect mVisibleRect;
    1455             :     nsRect mDirtyRect;
    1456             : 
    1457             :     static nsRect ComputeVisibleRectForFrame(nsDisplayListBuilder* aBuilder,
    1458             :                                              nsIFrame* aFrame,
    1459             :                                              const nsRect& aVisibleRect,
    1460             :                                              const nsRect& aDirtyRect,
    1461             :                                              nsRect* aOutDirtyRect) {
    1462             :       nsRect visible = aVisibleRect;
    1463             :       nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
    1464             : 
    1465             :       if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
    1466             :           aBuilder->IsPaintingToWindow()) {
    1467             :         // position: fixed items are reflowed into and only drawn inside the
    1468             :         // viewport, or the scroll position clamping scrollport size, if one is
    1469             :         // set.
    1470             :         nsIPresShell* ps = aFrame->PresShell();
    1471             :         if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
    1472             :           dirtyRectRelativeToDirtyFrame =
    1473             :             nsRect(nsPoint(0, 0), ps->GetScrollPositionClampingScrollPortSize());
    1474             :           visible = dirtyRectRelativeToDirtyFrame;
    1475             : #ifdef MOZ_WIDGET_ANDROID
    1476             :         } else {
    1477             :           dirtyRectRelativeToDirtyFrame =
    1478             :             nsRect(nsPoint(0, 0), aFrame->GetParent()->GetSize());
    1479             :           visible = dirtyRectRelativeToDirtyFrame;
    1480             : #endif
    1481             :         }
    1482             :       }
    1483             :       *aOutDirtyRect = dirtyRectRelativeToDirtyFrame - aFrame->GetPosition();
    1484             :       visible -= aFrame->GetPosition();
    1485             : 
    1486             :       nsRect overflowRect = aFrame->GetVisualOverflowRect();
    1487             : 
    1488             :       if (aFrame->IsTransformed() &&
    1489             :           mozilla::EffectCompositor::HasAnimationsForCompositor(aFrame,
    1490             :                                                                 eCSSProperty_transform)) {
    1491             :        /**
    1492             :         * Add a fuzz factor to the overflow rectangle so that elements only just
    1493             :         * out of view are pulled into the display list, so they can be
    1494             :         * prerendered if necessary.
    1495             :         */
    1496             :         overflowRect.Inflate(nsPresContext::CSSPixelsToAppUnits(32));
    1497             :       }
    1498             : 
    1499             :       visible.IntersectRect(visible, overflowRect);
    1500             :       aOutDirtyRect->IntersectRect(*aOutDirtyRect, overflowRect);
    1501             : 
    1502             :       return visible;
    1503             :     }
    1504             : 
    1505             :     nsRect GetVisibleRectForFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    1506             :                                   nsRect* aDirtyRect) {
    1507             :       return ComputeVisibleRectForFrame(aBuilder, aFrame, mVisibleRect, mDirtyRect, aDirtyRect);
    1508             :     }
    1509             :   };
    1510             : 
    1511             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutOfFlowDisplayDataProperty,
    1512             :                                       OutOfFlowDisplayData)
    1513             : 
    1514             :   struct DisplayListBuildingData {
    1515             :     RefPtr<AnimatedGeometryRoot> mModifiedAGR = nullptr;
    1516             :     nsRect mDirtyRect;
    1517             :   };
    1518             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayListBuildingRect, DisplayListBuildingData)
    1519             : 
    1520             :   NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayListBuildingDisplayPortRect, nsRect)
    1521             : 
    1522             :   static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
    1523             :   {
    1524             :     if (!aFrame->GetParent()) {
    1525             :       return nullptr;
    1526             :     }
    1527             :     return aFrame->GetParent()->GetProperty(OutOfFlowDisplayDataProperty());
    1528             :   }
    1529             : 
    1530             :   nsPresContext* CurrentPresContext() {
    1531             :     return CurrentPresShellState()->mPresShell->GetPresContext();
    1532             :   }
    1533             : 
    1534             :   OutOfFlowDisplayData* GetCurrentFixedBackgroundDisplayData()
    1535             :   {
    1536             :     auto& displayData = CurrentPresShellState()->mFixedBackgroundDisplayData;
    1537             :     return displayData ? displayData.ptr() : nullptr;
    1538             :   }
    1539             : 
    1540             :   /**
    1541             :    * Accumulates the bounds of box frames that have moz-appearance
    1542             :    * -moz-win-exclude-glass style. Used in setting glass margins on
    1543             :    * Windows.
    1544             :    *
    1545             :    * We set the window opaque region (from which glass margins are computed)
    1546             :    * to the intersection of the glass region specified here and the opaque
    1547             :    * region computed during painting. So the excluded glass region actually
    1548             :    * *limits* the extent of the opaque area reported to Windows. We limit it
    1549             :    * so that changes to the computed opaque region (which can vary based on
    1550             :    * region optimizations and the placement of UI elements) outside the
    1551             :    * -moz-win-exclude-glass area don't affect the glass margins reported to
    1552             :    * Windows; changing those margins willy-nilly can cause the Windows 7 glass
    1553             :    * haze effect to jump around disconcertingly.
    1554             :    */
    1555             :   void AddWindowExcludeGlassRegion(nsIFrame* aFrame, const nsRect& aBounds)
    1556             :   {
    1557             :     mWindowExcludeGlassRegion.Add(aFrame, aBounds);
    1558             :   }
    1559             : 
    1560             :   /**
    1561             :    * Returns the window exclude glass region.
    1562             :    */
    1563             :   nsRegion GetWindowExcludeGlassRegion() const
    1564             :   {
    1565             :     return mWindowExcludeGlassRegion.ToRegion();
    1566             :   }
    1567             : 
    1568             :   /**
    1569             :    * Accumulates opaque stuff into the window opaque region.
    1570             :    */
    1571             :   void AddWindowOpaqueRegion(const nsRegion& bounds) {
    1572             :     mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
    1573             :   }
    1574             :   /**
    1575             :    * Returns the window opaque region built so far. This may be incomplete
    1576             :    * since the opaque region is built during layer construction.
    1577             :    */
    1578             :   const nsRegion& GetWindowOpaqueRegion() {
    1579             :     return mWindowOpaqueRegion;
    1580             :   }
    1581             : 
    1582             :   /**
    1583             :    * Clears the window opaque region.
    1584             :    */
    1585             :   void ClearWindowOpaqueRegion()
    1586             :   {
    1587             :     mWindowOpaqueRegion.SetEmpty();
    1588             :   }
    1589             : 
    1590             :   void SetGlassDisplayItem(nsDisplayItem* aItem) {
    1591             :     if (mGlassDisplayItem) {
    1592             :       // Web pages or extensions could trigger this by using
    1593             :       // -moz-appearance:win-borderless-glass etc on their own elements.
    1594             :       // Keep the first one, since that will be the background of the root
    1595             :       // window
    1596             :       NS_WARNING("Multiple glass backgrounds found?");
    1597             :     } else {
    1598             :       mGlassDisplayItem = aItem;
    1599             :     }
    1600             :   }
    1601             :   bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem);
    1602             : 
    1603             :   void SetContainsPluginItem() { mContainsPluginItem = true; }
    1604             :   bool ContainsPluginItem() { return mContainsPluginItem; }
    1605             : 
    1606             :   /**
    1607             :    * mContainsBlendMode is true if we processed a display item that
    1608             :    * has a blend mode attached. We do this so we can insert a
    1609             :    * nsDisplayBlendContainer in the parent stacking context.
    1610             :    */
    1611             :   void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; }
    1612             :   bool ContainsBlendMode() const { return mContainsBlendMode; }
    1613             : 
    1614             :   DisplayListClipState& ClipState() { return mClipState; }
    1615             :   const ActiveScrolledRoot* CurrentActiveScrolledRoot() { return mCurrentActiveScrolledRoot; }
    1616             :   const ActiveScrolledRoot* CurrentAncestorASRStackingContextContents() { return mCurrentContainerASR; }
    1617             : 
    1618             :   /**
    1619             :    * Add the current frame to the will-change budget if possible and
    1620             :    * remeber the outcome. Subsequent calls to IsInWillChangeBudget
    1621             :    * will return the same value as return here.
    1622             :    */
    1623             :   bool AddToWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
    1624             : 
    1625             :   /**
    1626             :    * This will add the current frame to the will-change budget the first
    1627             :    * time it is seen. On subsequent calls this will return the same
    1628             :    * answer. This effectively implements a first-come, first-served
    1629             :    * allocation of the will-change budget.
    1630             :    */
    1631             :   bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
    1632             : 
    1633             :   void ClearWillChangeBudget(nsIFrame* aFrame);
    1634             : 
    1635             :   void EnterSVGEffectsContents(nsDisplayList* aHoistedItemsStorage);
    1636             :   void ExitSVGEffectsContents();
    1637             : 
    1638             :   /**
    1639             :    * Note: if changing the conditions under which scroll info layers
    1640             :    * are created, make a corresponding change to
    1641             :    * ScrollFrameWillBuildScrollInfoLayer() in nsSliderFrame.cpp.
    1642             :    */
    1643             :   bool ShouldBuildScrollInfoItemsForHoisting() const
    1644             :   { return mSVGEffectsBuildingDepth > 0; }
    1645             : 
    1646             :   void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
    1647             : 
    1648             :   /**
    1649             :    * A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
    1650             :    *
    1651             :    * mPreserves3DCtx is used by class AutoAccumulateTransform &
    1652             :    * AutoAccumulateRect to passing data between frames in the 3D
    1653             :    * context.  If a frame create a new 3D context, it should restore
    1654             :    * the value of mPreserves3DCtx before returning back to the parent.
    1655             :    * This class do it for the users.
    1656             :    */
    1657             :   class AutoPreserves3DContext {
    1658             :   public:
    1659             :     explicit AutoPreserves3DContext(nsDisplayListBuilder* aBuilder)
    1660             :       : mBuilder(aBuilder)
    1661             :       , mSavedCtx(aBuilder->mPreserves3DCtx) {}
    1662             :     ~AutoPreserves3DContext() {
    1663             :       mBuilder->mPreserves3DCtx = mSavedCtx;
    1664             :     }
    1665             : 
    1666             :   private:
    1667             :     nsDisplayListBuilder* mBuilder;
    1668             :     Preserves3DContext mSavedCtx;
    1669             :   };
    1670             : 
    1671             :   const nsRect GetPreserves3DRect() const {
    1672             :     return mPreserves3DCtx.mVisibleRect;
    1673             :   }
    1674             :   void SavePreserves3DRect() {
    1675             :     mPreserves3DCtx.mVisibleRect = mVisibleRect;
    1676             :   }
    1677             : 
    1678             :   bool IsBuildingInvisibleItems() const { return mBuildingInvisibleItems; }
    1679             :   void SetBuildingInvisibleItems(bool aBuildingInvisibleItems) {
    1680             :     mBuildingInvisibleItems = aBuildingInvisibleItems;
    1681             :   }
    1682             : 
    1683             :   bool MarkFrameModifiedDuringBuilding(nsIFrame* aFrame)
    1684             :   {
    1685             :     if (!aFrame->IsFrameModified()) {
    1686             :       mModifiedFramesDuringBuilding.AppendElement(aFrame);
    1687             :       aFrame->SetFrameIsModified(true);
    1688             :       return true;
    1689             :     }
    1690             :     return false;
    1691             :   }
    1692             : 
    1693             :   bool MarkCurrentFrameModifiedDuringBuilding()
    1694             :   {
    1695             :     if (MarkFrameModifiedDuringBuilding(const_cast<nsIFrame*>(mCurrentFrame))) {
    1696             :       mInInvalidSubtree = true;
    1697             :       mDirtyRect = mVisibleRect;
    1698             :       return true;
    1699             :     }
    1700             :     return false;
    1701             :   }
    1702             : 
    1703             :   void RebuildAllItemsInCurrentSubtree()
    1704             :   {
    1705             :     mInInvalidSubtree = true;
    1706             :     mDirtyRect = mVisibleRect;
    1707             :   }
    1708             : 
    1709             :   /**
    1710             :    * This is a convenience function to ease the transition until AGRs and ASRs
    1711             :    * are unified.
    1712             :    */
    1713             :   AnimatedGeometryRoot* AnimatedGeometryRootForASR(const ActiveScrolledRoot* aASR);
    1714             : 
    1715             :   bool HitTestIsForVisibility() const {
    1716             :     return mHitTestIsForVisibility;
    1717             :   }
    1718             :   void SetHitTestIsForVisibility(bool aHitTestIsForVisibility) {
    1719             :     mHitTestIsForVisibility = aHitTestIsForVisibility;
    1720             :   }
    1721             : 
    1722             :   /**
    1723             :    * Represents a region composed of frame/rect pairs.
    1724             :    * WeakFrames are used to track whether a rect still belongs to the region.
    1725             :    * Modified frames and rects are removed and re-added to the region if needed.
    1726             :    */
    1727             :   struct WeakFrameRegion {
    1728             :     std::vector<WeakFrame> mFrames;
    1729             :     nsTArray<pixman_box32_t> mRects;
    1730             : 
    1731             :     void Add(nsIFrame* aFrame, const nsRect& aRect)
    1732             :     {
    1733             :       mFrames.emplace_back(aFrame);
    1734             :       mRects.AppendElement(nsRegion::RectToBox(aRect));
    1735             :     }
    1736             : 
    1737             :     void Add(nsIFrame* aFrame, const mozilla::gfx::IntRect& aRect)
    1738             :     {
    1739             :       mFrames.emplace_back(aFrame);
    1740             :       mRects.AppendElement(nsRegion::RectToBox(aRect));
    1741             :     }
    1742             : 
    1743             :     void Clear()
    1744             :     {
    1745             :       mFrames.clear();
    1746             :       mRects.Clear();
    1747             :     }
    1748             : 
    1749             :     typedef mozilla::gfx::ArrayView<pixman_box32_t> BoxArrayView;
    1750             : 
    1751             :     nsRegion ToRegion() const
    1752             :     {
    1753             :       return nsRegion(BoxArrayView(mRects));
    1754             :     }
    1755             : 
    1756             :     LayoutDeviceIntRegion ToLayoutDeviceIntRegion() const
    1757             :     {
    1758             :       return LayoutDeviceIntRegion(BoxArrayView(mRects));
    1759             :     }
    1760             :   };
    1761             : 
    1762             : private:
    1763             :   bool MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame);
    1764             : 
    1765             :   /**
    1766             :    * Returns whether a frame acts as an animated geometry root, optionally
    1767             :    * returning the next ancestor to check.
    1768             :    */
    1769             :   AGRState IsAnimatedGeometryRoot(nsIFrame* aFrame,
    1770             :                                   bool& aIsAsync,
    1771             :                                   nsIFrame** aParent = nullptr);
    1772             : 
    1773             :   /**
    1774             :    * Returns the nearest ancestor frame to aFrame that is considered to have
    1775             :    * (or will have) animated geometry. This can return aFrame.
    1776             :    */
    1777             :   nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame, bool& aIsAsync);
    1778             : 
    1779             :   /**
    1780             :    * Returns true if nsDisplayCompositorHitTestInfo item should be build for
    1781             :    * |aFrame|. Otherwise returns false. If |aBuildNew| is true, reusing the
    1782             :    * previous hit test info will not be considered.
    1783             :    */
    1784             :   bool ShouldBuildCompositorHitTestInfo(const nsIFrame* aFrame,
    1785             :                                         const mozilla::gfx::CompositorHitTestInfo& aInfo,
    1786             :                                         const bool aBuildNew) const;
    1787             : 
    1788             :   friend class nsDisplayCanvasBackgroundImage;
    1789             :   friend class nsDisplayBackgroundImage;
    1790             :   friend class nsDisplayFixedPosition;
    1791             :   friend class nsDisplayPerspective;
    1792             :   AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
    1793             : 
    1794             :   friend class nsDisplayItem;
    1795             :   friend class nsDisplayOwnLayer;
    1796             :   friend struct RetainedDisplayListBuilder;
    1797             :   AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
    1798             : 
    1799             :   AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
    1800             :                                         bool aIsAsync,
    1801             :                                         AnimatedGeometryRoot* aParent = nullptr);
    1802             : 
    1803             :   nsDataHashtable<nsPtrHashKey<nsIFrame>, RefPtr<AnimatedGeometryRoot>> mFrameToAnimatedGeometryRootMap;
    1804             : 
    1805             :   /**
    1806             :    * Add the current frame to the AGR budget if possible and remember
    1807             :    * the outcome. Subsequent calls will return the same value as
    1808             :    * returned here.
    1809             :    */
    1810             :   bool AddToAGRBudget(nsIFrame* aFrame);
    1811             : 
    1812             :   struct PresShellState {
    1813             :     nsIPresShell* mPresShell;
    1814             : #ifdef DEBUG
    1815             :     mozilla::Maybe<nsAutoLayoutPhase> mAutoLayoutPhase;
    1816             : #endif
    1817             :     nsIFrame*     mCaretFrame;
    1818             :     nsRect        mCaretRect;
    1819             :     mozilla::Maybe<OutOfFlowDisplayData> mFixedBackgroundDisplayData;
    1820             :     uint32_t      mFirstFrameMarkedForDisplay;
    1821             :     uint32_t      mFirstFrameWithOOFData;
    1822           0 :     bool          mIsBackgroundOnly;
    1823           0 :     // This is a per-document flag turning off event handling for all content
    1824             :     // in the document, and is set when we enter a subdocument for a pointer-
    1825           0 :     // events:none frame.
    1826             :     bool          mInsidePointerEventsNoneDoc;
    1827             :   };
    1828             : 
    1829             :   PresShellState* CurrentPresShellState() {
    1830             :     NS_ASSERTION(mPresShellStates.Length() > 0,
    1831             :                  "Someone forgot to enter a presshell");
    1832             :     return &mPresShellStates[mPresShellStates.Length() - 1];
    1833             :   }
    1834             : 
    1835             :   struct DocumentWillChangeBudget {
    1836             :     DocumentWillChangeBudget()
    1837             :       : mBudget(0)
    1838             :     {}
    1839             : 
    1840             :     uint32_t mBudget;
    1841             :   };
    1842             : 
    1843             :   struct FrameWillChangeBudget {
    1844             :     FrameWillChangeBudget(nsIFrame* aFrame, uint32_t aUsage)
    1845             :       : mFrame(aFrame)
    1846             :       , mUsage(aUsage)
    1847             :     {}
    1848             : 
    1849             :     nsIFrame* mFrame;
    1850             :     uint32_t mUsage;
    1851             :   };
    1852             : 
    1853             :   nsIFrame* const                mReferenceFrame;
    1854             :   nsIFrame*                      mIgnoreScrollFrame;
    1855             :   nsDisplayCompositorHitTestInfo* mCompositorHitTestInfo;
    1856             : 
    1857             :   nsPresArena mPool;
    1858             : 
    1859             :   RefPtr<mozilla::dom::Selection> mBoundingSelection;
    1860             :   AutoTArray<PresShellState,8> mPresShellStates;
    1861             :   AutoTArray<nsIFrame*,400>    mFramesMarkedForDisplay;
    1862             :   AutoTArray<nsIFrame*,40>       mFramesMarkedForDisplayIfVisible;
    1863             :   AutoTArray<nsIFrame*,20>     mFramesWithOOFData;
    1864             :   nsClassHashtable<nsPtrHashKey<nsDisplayItem>, nsTArray<ThemeGeometry>> mThemeGeometries;
    1865             :   nsDisplayTableItem*            mCurrentTableItem;
    1866             :   DisplayListClipState           mClipState;
    1867             :   const ActiveScrolledRoot*      mCurrentActiveScrolledRoot;
    1868             :   const ActiveScrolledRoot*      mCurrentContainerASR;
    1869             :   // mCurrentFrame is the frame that we're currently calling (or about to call)
    1870             :   // BuildDisplayList on.
    1871             :   const nsIFrame*                mCurrentFrame;
    1872             :   // The reference frame for mCurrentFrame.
    1873             :   const nsIFrame*                mCurrentReferenceFrame;
    1874             :   // The offset from mCurrentFrame to mCurrentReferenceFrame.
    1875             :   nsPoint                        mCurrentOffsetToReferenceFrame;
    1876             : 
    1877             :   RefPtr<AnimatedGeometryRoot>   mRootAGR;
    1878             :   RefPtr<AnimatedGeometryRoot>   mCurrentAGR;
    1879             : 
    1880             :   // will-change budget tracker
    1881             :   nsDataHashtable<nsPtrHashKey<nsPresContext>, DocumentWillChangeBudget>
    1882             :                                  mWillChangeBudget;
    1883             : 
    1884             :   // Any frame listed in this set is already counted in the budget
    1885             :   // and thus is in-budget.
    1886             :   nsDataHashtable<nsPtrHashKey<nsIFrame>, uint32_t> mWillChangeBudgetSet;
    1887             : 
    1888             :   // Area of animated geometry root budget already allocated
    1889             :   uint32_t mUsedAGRBudget;
    1890             :   // Set of frames already counted in budget
    1891             :   nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
    1892             : 
    1893             :   nsTArray<nsIFrame*>           mModifiedFramesDuringBuilding;
    1894             : 
    1895             :   // Relative to mCurrentFrame.
    1896             :   nsRect                         mVisibleRect;
    1897             :   nsRect                         mDirtyRect;
    1898             : 
    1899             :   // Tracked regions used for retained display list.
    1900             :   WeakFrameRegion                mWindowExcludeGlassRegion;
    1901             :   WeakFrameRegion                mRetainedWindowDraggingRegion;
    1902             :   WeakFrameRegion                mRetainedWindowNoDraggingRegion;
    1903             : 
    1904             :   // Optimized versions for non-retained display list.
    1905             :   LayoutDeviceIntRegion          mWindowDraggingRegion;
    1906             :   LayoutDeviceIntRegion          mWindowNoDraggingRegion;
    1907             : 
    1908             :   // Window opaque region is calculated during layer building.
    1909             :   nsRegion                       mWindowOpaqueRegion;
    1910             : 
    1911             :   // The display item for the Windows window glass background, if any
    1912             :   nsDisplayItem*                 mGlassDisplayItem;
    1913             :   // A temporary list that we append scroll info items to while building
    1914             :   // display items for the contents of frames with SVG effects.
    1915             :   // Only non-null when ShouldBuildScrollInfoItemsForHoisting() is true.
    1916             :   // This is a pointer and not a real nsDisplayList value because the
    1917             :   // nsDisplayList class is defined below this class, so we can't use it here.
    1918             :   nsDisplayList*                 mScrollInfoItemsForHoisting;
    1919             :   nsTArray<RefPtr<ActiveScrolledRoot>>  mActiveScrolledRoots;
    1920             :   std::unordered_set<
    1921             :     const DisplayItemClipChain*,
    1922             :     DisplayItemClipChainHasher,
    1923             :     DisplayItemClipChainEqualer> mClipDeduplicator;
    1924             :   std::list<DisplayItemClipChain*> mClipChainsToDestroy;
    1925             :   nsTArray<nsDisplayItem*> mTemporaryItems;
    1926             :   const ActiveScrolledRoot*      mActiveScrolledRootForRootScrollframe;
    1927             :   nsDisplayListBuilderMode       mMode;
    1928             :   ViewID                         mCurrentScrollParentId;
    1929             :   ViewID                         mCurrentScrollbarTarget;
    1930             :   MaybeScrollDirection           mCurrentScrollbarDirection;
    1931             :   Preserves3DContext             mPreserves3DCtx;
    1932             :   int32_t                        mSVGEffectsBuildingDepth;
    1933             :   // When we are inside a filter, the current ASR at the time we entered the
    1934             :   // filter. Otherwise nullptr.
    1935             :   const ActiveScrolledRoot*      mFilterASR;
    1936             :   bool                           mContainsBlendMode;
    1937             :   bool                           mIsBuildingScrollbar;
    1938             :   bool                           mCurrentScrollbarWillHaveLayer;
    1939             :   bool                           mBuildCaret;
    1940             :   bool                           mRetainingDisplayList;
    1941             :   bool                           mPartialUpdate;
    1942             :   bool                           mIgnoreSuppression;
    1943             :   bool                           mIsAtRootOfPseudoStackingContext;
    1944             :   bool                           mIncludeAllOutOfFlows;
    1945             :   bool                           mDescendIntoSubdocuments;
    1946             :   bool                           mSelectedFramesOnly;
    1947             :   bool                           mAllowMergingAndFlattening;
    1948             :   bool                           mWillComputePluginGeometry;
    1949             :   // True when we're building a display list that's directly or indirectly
    1950             :   // under an nsDisplayTransform
    1951             :   bool                           mInTransform;
    1952             :   bool                           mInPageSequence;
    1953             :   bool                           mIsInChromePresContext;
    1954             :   bool                           mSyncDecodeImages;
    1955             :   bool                           mIsPaintingToWindow;
    1956             :   bool                           mIsCompositingCheap;
    1957             :   bool                           mContainsPluginItem;
    1958             :   bool                           mAncestorHasApzAwareEventHandler;
    1959             :   // True when the first async-scrollable scroll frame for which we build a
    1960             :   // display list has a display port. An async-scrollable scroll frame is one
    1961             :   // which WantsAsyncScroll().
    1962             :   bool                           mHaveScrollableDisplayPort;
    1963             :   bool                           mWindowDraggingAllowed;
    1964             :   bool                           mIsBuildingForPopup;
    1965             :   bool                           mForceLayerForScrollParent;
    1966             :   bool                           mAsyncPanZoomEnabled;
    1967             :   bool                           mBuildingInvisibleItems;
    1968             :   bool                           mHitTestIsForVisibility;
    1969             :   bool                           mIsBuilding;
    1970             :   bool                           mInInvalidSubtree;
    1971             :   bool                           mBuildCompositorHitTestInfo;
    1972             :   bool                           mLessEventRegionItems;
    1973             :   bool                           mDisablePartialUpdates;
    1974             :   bool                           mPartialBuildFailed;
    1975             : };
    1976             : 
    1977             : class nsDisplayItem;
    1978             : class nsDisplayList;
    1979             : class RetainedDisplayList;
    1980             : /**
    1981             :  * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
    1982           0 :  * nsDisplayItemLink holds the link. The lists are linked from lowest to
    1983             :  * highest in z-order.
    1984             :  */
    1985             : class nsDisplayItemLink {
    1986             :   // This is never instantiated directly, so no need to count constructors and
    1987             :   // destructors.
    1988             : protected:
    1989             :   nsDisplayItemLink() : mAbove(nullptr) {}
    1990             :   nsDisplayItemLink(const nsDisplayItemLink&) : mAbove(nullptr) {}
    1991             :   nsDisplayItem* mAbove;
    1992             : 
    1993             :   friend class nsDisplayList;
    1994             : };
    1995             : 
    1996             : class nsDisplayWrapList;
    1997           0 : 
    1998             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    1999           0 : void AssertUniqueItem(nsDisplayItem* aItem);
    2000             : #endif
    2001             : 
    2002           0 : template<typename T, typename... Args>
    2003           0 : MOZ_ALWAYS_INLINE T*
    2004           0 : MakeDisplayItem(nsDisplayListBuilder* aBuilder, Args&&... aArgs)
    2005           0 : {
    2006           0 :   T* item = new (aBuilder) T(aBuilder, std::forward<Args>(aArgs)...);
    2007           0 : 
    2008             :   const mozilla::SmallPointerArray<mozilla::DisplayItemData>& array =
    2009             :     item->Frame()->DisplayItemData();
    2010             :   for (uint32_t i = 0; i < array.Length(); i++) {
    2011             :     mozilla::DisplayItemData* did = array.ElementAt(i);
    2012             :     if (did->GetDisplayItemKey() == item->GetPerFrameKey()) {
    2013             :       if (!did->HasMergedFrames()) {
    2014           0 :         item->SetDisplayItemData(did);
    2015           0 :       }
    2016           0 :       break;
    2017           0 :     }
    2018             :   }
    2019             : 
    2020             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    2021           0 :   if (aBuilder->IsRetainingDisplayList() &&
    2022             :       !aBuilder->IsInPageSequence() &&
    2023             :       aBuilder->IsBuilding()) {
    2024             :     AssertUniqueItem(item);
    2025             :   }
    2026             : #endif
    2027             : 
    2028             :   return item;
    2029             : }
    2030             : 
    2031             : /**
    2032             :  * This is the unit of rendering and event testing. Each instance of this
    2033             :  * class represents an entity that can be drawn on the screen, e.g., a
    2034             :  * frame's CSS background, or a frame's text string.
    2035             :  *
    2036             :  * nsDisplayItems can be containers --- i.e., they can perform hit testing
    2037             :  * and painting by recursively traversing a list of child items.
    2038             :  *
    2039             :  * These are arena-allocated during display list construction. A typical
    2040             :  * subclass would just have a frame pointer, so its object would be just three
    2041             :  * pointers (vtable, next-item, frame).
    2042             :  *
    2043             :  * Display items belong to a list at all times (except temporarily as they
    2044             :  * move from one list to another).
    2045             :  */
    2046             : class nsDisplayItem : public nsDisplayItemLink {
    2047             : public:
    2048             :   typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
    2049             :   typedef mozilla::DisplayItemClip DisplayItemClip;
    2050             :   typedef mozilla::DisplayItemClipChain DisplayItemClipChain;
    2051             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
    2052             :   typedef mozilla::layers::FrameMetrics FrameMetrics;
    2053             :   typedef mozilla::layers::ScrollMetadata ScrollMetadata;
    2054             :   typedef mozilla::layers::FrameMetrics::ViewID ViewID;
    2055             :   typedef mozilla::layers::Layer Layer;
    2056             :   typedef mozilla::layers::LayerManager LayerManager;
    2057             :   typedef mozilla::layers::StackingContextHelper StackingContextHelper;
    2058             :   typedef mozilla::layers::WebRenderCommand WebRenderCommand;
    2059             :   typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
    2060             :   typedef mozilla::LayerState LayerState;
    2061             :   typedef mozilla::image::imgDrawingParams imgDrawingParams;
    2062             :   typedef mozilla::image::ImgDrawResult ImgDrawResult;
    2063             :   typedef class mozilla::gfx::DrawTarget DrawTarget;
    2064             : 
    2065             :   // This is never instantiated directly (it has pure virtual methods), so no
    2066             :   // need to count constructors and destructors.
    2067             :   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    2068             :   nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    2069             :                 const ActiveScrolledRoot* aActiveScrolledRoot,
    2070             :                 bool aAnonymous = false);
    2071             : 
    2072             :   /**
    2073             :    * This constructor is only used in rare cases when we need to construct
    2074             :    * temporary items.
    2075             :    */
    2076             :   explicit nsDisplayItem(nsIFrame* aFrame)
    2077             :     : mFrame(aFrame)
    2078             :     , mClipChain(nullptr)
    2079             :     , mClip(nullptr)
    2080             :     , mActiveScrolledRoot(nullptr)
    2081             :     , mReferenceFrame(nullptr)
    2082             :     , mAnimatedGeometryRoot(nullptr)
    2083             :     , mForceNotVisible(false)
    2084             :     , mDisableSubpixelAA(false)
    2085             :     , mReusedItem(false)
    2086             :     , mBackfaceHidden(mFrame->In3DContextAndBackfaceIsHidden())
    2087             :     , mPaintRectValid(false)
    2088             : #ifdef MOZ_DUMP_PAINTING
    2089           0 :     , mPainted(false)
    2090           0 : #endif
    2091           0 :   {
    2092           0 :     MOZ_COUNT_CTOR(nsDisplayItem);
    2093             :   }
    2094           0 : 
    2095             : protected:
    2096             :   virtual ~nsDisplayItem() {
    2097           0 :     MOZ_COUNT_DTOR(nsDisplayItem);
    2098             :     if (mFrame) {
    2099           0 :       mFrame->RemoveDisplayItem(this);
    2100           0 :     }
    2101           0 :   }
    2102           0 : public:
    2103             : 
    2104           0 :   virtual void Destroy(nsDisplayListBuilder* aBuilder)
    2105             :   {
    2106           0 :     DisplayItemType type = GetType();
    2107           0 :     this->~nsDisplayItem();
    2108           0 :     aBuilder->Destroy(type, this);
    2109           0 :   }
    2110             : 
    2111           0 :   virtual void RestoreState()
    2112             :   {
    2113           0 :     mClipChain = mState.mClipChain;
    2114           0 :     mClip = mState.mClip;
    2115           0 :     mDisableSubpixelAA = false;
    2116           0 :   }
    2117             : 
    2118           0 :   virtual void RemoveFrame(nsIFrame* aFrame)
    2119             :   {
    2120             :     if (mFrame && aFrame == mFrame) {
    2121             :       MOZ_ASSERT(!mFrame->HasDisplayItem(this));
    2122             :       mFrame = nullptr;
    2123           0 :       mDisplayItemData = nullptr;
    2124           0 :     }
    2125             :   }
    2126             : 
    2127             :   /**
    2128             :    * Downcasts this item to nsDisplayWrapList, if possible.
    2129           0 :    */
    2130             :   virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; }
    2131           0 :   virtual nsDisplayWrapList* AsDisplayWrapList() { return nullptr; }
    2132             : 
    2133             :   /**
    2134             :    * Create a clone of this item.
    2135             :    */
    2136             :   virtual nsDisplayItem* Clone(nsDisplayListBuilder* aBuilder) const
    2137             :   {
    2138             :     return nullptr;
    2139             :   }
    2140           0 : 
    2141           0 :   nsDisplayItem(const nsDisplayItem&) = delete;
    2142             :   /**
    2143           0 :    * The custom copy-constructor is implemented to prevent copying the saved
    2144             :    * state of the item.
    2145           0 :    * This is currently only used when creating temporary items for merging.
    2146             :    */
    2147             :   nsDisplayItem(nsDisplayListBuilder* aBuilder, const nsDisplayItem& aOther)
    2148             :     : mFrame(aOther.mFrame)
    2149             :     , mClipChain(aOther.mClipChain)
    2150           0 :     , mClip(aOther.mClip)
    2151           0 :     , mActiveScrolledRoot(aOther.mActiveScrolledRoot)
    2152             :     , mReferenceFrame(aOther.mReferenceFrame)
    2153           0 :     , mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot)
    2154             :     , mToReferenceFrame(aOther.mToReferenceFrame)
    2155             :     , mBuildingRect(aOther.mBuildingRect)
    2156           0 :     , mPaintRect(aOther.mPaintRect)
    2157             :     , mForceNotVisible(aOther.mForceNotVisible)
    2158             :     , mDisableSubpixelAA(aOther.mDisableSubpixelAA)
    2159           0 :     , mReusedItem(false)
    2160           0 :     , mBackfaceHidden(mFrame->In3DContextAndBackfaceIsHidden())
    2161             :     , mPaintRectValid(false)
    2162             : #ifdef MOZ_DUMP_PAINTING
    2163             :     , mPainted(false)
    2164             : #endif
    2165             :   {
    2166             :     MOZ_COUNT_CTOR(nsDisplayItem);
    2167             :   }
    2168             : 
    2169             : 
    2170             :   struct HitTestState {
    2171             :     explicit HitTestState() : mInPreserves3D(false) {}
    2172             : 
    2173             :     ~HitTestState() {
    2174             :       NS_ASSERTION(mItemBuffer.Length() == 0,
    2175             :                    "mItemBuffer should have been cleared");
    2176             :     }
    2177             : 
    2178             :     // Handling transform items for preserve 3D frames.
    2179             :     bool mInPreserves3D;
    2180             :     AutoTArray<nsDisplayItem*, 100> mItemBuffer;
    2181             :   };
    2182             : 
    2183             :   /**
    2184             :    * Some consecutive items should be rendered together as a unit, e.g.,
    2185             :    * outlines for the same element. For this, we need a way for items to
    2186             :    * identify their type. We use the type for other purposes too.
    2187           0 :    */
    2188             :   virtual DisplayItemType GetType() const = 0;
    2189             :   /**
    2190             :    * Pairing this with the GetUnderlyingFrame() pointer gives a key that
    2191             :    * uniquely identifies this display item in the display item tree.
    2192             :    * XXX check nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper
    2193             :    */
    2194             :   virtual uint32_t GetPerFrameKey() const { return uint32_t(GetType()); }
    2195             : 
    2196             :   uint8_t GetFlags() { return GetDisplayItemFlagsForType(GetType()); }
    2197             : 
    2198             :   /**
    2199             :    * This is called after we've constructed a display list for event handling.
    2200             :    * When this is called, we've already ensured that aRect intersects the
    2201             :    * item's bounds and that clipping has been taking into account.
    2202             :    *
    2203             :    * @param aRect the point or rect being tested, relative to the reference
    2204           0 :    * frame. If the width and height are both 1 app unit, it indicates we're
    2205           0 :    * hit testing a point, not a rect.
    2206             :    * @param aState must point to a HitTestState. If you don't have one,
    2207             :    * just create one with the default constructor and pass it in.
    2208             :    * @param aOutFrames each item appends the frame(s) in this display item that
    2209             :    * the rect is considered over (if any) to aOutFrames.
    2210             :    */
    2211           0 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    2212             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
    2213           0 :   /**
    2214           0 :    * @return the frame that this display item is based on. This is used to sort
    2215             :    * items by z-index and content order and for some other uses. Never
    2216             :    * returns null.
    2217             :    */
    2218             :   inline nsIFrame* Frame() const
    2219             :   {
    2220             :     MOZ_ASSERT(mFrame, "Trying to use display item after deletion!");
    2221           0 :     return mFrame;
    2222             :   }
    2223           0 : 
    2224             :   /**
    2225             :    * @return the nsIFrame that provides the style data, and should
    2226           0 :    * be checked when deciding if this display item can be reused.
    2227             :    */
    2228           0 :   virtual nsIFrame* FrameForInvalidation() const
    2229             :   {
    2230             :     return mFrame;
    2231             :   }
    2232             : 
    2233             :   virtual bool HasDeletedFrame() const { return !mFrame; }
    2234             : 
    2235             :   virtual nsIFrame* StyleFrame() const { return mFrame; }
    2236             : 
    2237             :   /**
    2238             :    * Compute the used z-index of our frame; returns zero for elements to which
    2239             :    * z-index does not apply, and for z-index:auto.
    2240             :    * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
    2241             :    */
    2242             :   virtual int32_t ZIndex() const;
    2243             :   /**
    2244             :    * The default bounds is the frame border rect.
    2245             :    * @param aSnap *aSnap is set to true if the returned rect will be
    2246             :    * snapped to nearest device pixel edges during actual drawing.
    2247           0 :    * It might be set to false and snap anyway, so code computing the set of
    2248             :    * pixels affected by this display item needs to round outwards to pixel
    2249             :    * boundaries when *aSnap is set to false.
    2250           0 :    * This does not take the item's clipping into account.
    2251           0 :    * @return a rectangle relative to aBuilder->ReferenceFrame() that
    2252             :    * contains the area drawn by this display item
    2253             :    */
    2254           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    2255             :                            bool* aSnap) const
    2256             :   {
    2257           0 :     *aSnap = false;
    2258           0 :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    2259             :   }
    2260             : 
    2261             :   virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder,
    2262             :                                   bool* aSnap) const
    2263             :   {
    2264             :     *aSnap = false;
    2265           0 :     return nsRegion();
    2266             :   }
    2267             : 
    2268             :   /**
    2269             :    * Returns true if nothing will be rendered inside aRect, false if uncertain.
    2270             :    * aRect is assumed to be contained in this item's bounds.
    2271             :    */
    2272             :   virtual bool IsInvisibleInRect(const nsRect& aRect) const { return false; }
    2273             : 
    2274           0 :   /**
    2275             :    * Returns the result of GetBounds intersected with the item's clip.
    2276           0 :    * The intersection is approximate since rounded corners are not taking into
    2277             :    * account.
    2278             :    */
    2279           0 :   nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder) const;
    2280             : 
    2281           0 :   nsRect GetBorderRect() const
    2282             :   {
    2283             :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    2284             :   }
    2285             : 
    2286             :   nsRect GetPaddingRect() const
    2287             :   {
    2288             :     return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
    2289             :   }
    2290             : 
    2291             :   nsRect GetContentRect() const
    2292             :   {
    2293           0 :     return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
    2294             :   }
    2295           0 : 
    2296           0 :   /**
    2297           0 :    * Checks if the frame(s) owning this display item have been marked as invalid,
    2298             :    * and needing repainting.
    2299             :    */
    2300             :   virtual bool IsInvalid(nsRect& aRect) const
    2301             :   {
    2302             :     bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
    2303             :     aRect += ToReferenceFrame();
    2304             :     return result;
    2305             :   }
    2306             : 
    2307             :   /**
    2308             :    * Creates and initializes an nsDisplayItemGeometry object that retains the current
    2309             :    * areas covered by this display item. These need to retain enough information
    2310             :    * such that they can be compared against a future nsDisplayItem of the same type,
    2311             :    * and determine if repainting needs to happen.
    2312             :    *
    2313           0 :    * Subclasses wishing to store more information need to override both this
    2314             :    * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry
    2315           0 :    * subclass.
    2316             :    *
    2317             :    * The default implementation tracks both the display item bounds, and the frame's
    2318             :    * border rect.
    2319             :    */
    2320             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
    2321             :   {
    2322             :     return new nsDisplayItemGenericGeometry(this, aBuilder);
    2323             :   }
    2324             : 
    2325             :   /**
    2326             :    * Compares an nsDisplayItemGeometry object from a previous paint against the
    2327             :    * current item. Computes if the geometry of the item has changed, and the
    2328             :    * invalidation area required for correct repainting.
    2329             :    *
    2330             :    * The existing geometry will have been created from a display item with a
    2331             :    * matching GetPerFrameKey()/mFrame pair to the current item.
    2332             :    *
    2333             :    * The default implementation compares the display item bounds, and the frame's
    2334           0 :    * border rect, and invalidates the entire bounds if either rect changes.
    2335             :    *
    2336             :    * @param aGeometry The geometry of the matching display item from the
    2337             :    * previous paint.
    2338           0 :    * @param aInvalidRegion Output param, the region to invalidate, or
    2339             :    * unchanged if none.
    2340           0 :    */
    2341           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    2342           0 :                                          const nsDisplayItemGeometry* aGeometry,
    2343             :                                          nsRegion* aInvalidRegion) const
    2344           0 :   {
    2345             :     const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
    2346             :     bool snap;
    2347             :     if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
    2348             :         !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
    2349             :       aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
    2350           0 :     }
    2351             :   }
    2352             : 
    2353             :   /**
    2354             :    * An alternative default implementation of ComputeInvalidationRegion,
    2355           0 :    * that instead invalidates only the changed area between the two items.
    2356             :    */
    2357           0 :   void ComputeInvalidationRegionDifference(nsDisplayListBuilder* aBuilder,
    2358             :                                            const nsDisplayItemBoundsGeometry* aGeometry,
    2359           0 :                                            nsRegion* aInvalidRegion) const
    2360           0 :   {
    2361           0 :     bool snap;
    2362             :     nsRect bounds = GetBounds(aBuilder, &snap);
    2363           0 : 
    2364             :     if (!aGeometry->mBounds.IsEqualInterior(bounds)) {
    2365             :       nscoord radii[8];
    2366           0 :       if (aGeometry->mHasRoundedCorners ||
    2367             :           Frame()->GetBorderRadii(radii)) {
    2368             :         aInvalidRegion->Or(aGeometry->mBounds, bounds);
    2369             :       } else {
    2370             :         aInvalidRegion->Xor(aGeometry->mBounds, bounds);
    2371             :       }
    2372             :     }
    2373             :   }
    2374             : 
    2375             :   /**
    2376             :    * @param aSnap set to true if the edges of the rectangles of the opaque
    2377             :    * region would be snapped to device pixels when drawing
    2378           0 :    * @return a region of the item that is opaque --- that is, every pixel
    2379             :    * that is visible is painted with an opaque
    2380             :    * color. This is useful for determining when one piece
    2381           0 :    * of content completely obscures another so that we can do occlusion
    2382           0 :    * culling.
    2383             :    * This does not take clipping into account.
    2384             :    */
    2385             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    2386             :                                    bool* aSnap) const
    2387             :   {
    2388           0 :     *aSnap = false;
    2389             :     return nsRegion();
    2390           0 :   }
    2391             :   /**
    2392             :    * @return Some(nscolor) if the item is guaranteed to paint every pixel in its
    2393             :    * bounds with the same (possibly translucent) color
    2394             :    */
    2395             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const
    2396             :   {
    2397           0 :     return mozilla::Nothing();
    2398             :   }
    2399           0 : 
    2400             :   /**
    2401             :    * @return true if the contents of this item are rendered fixed relative
    2402           0 :    * to the nearest viewport.
    2403             :    */
    2404           0 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const
    2405             :   {
    2406             :     return false;
    2407             :   }
    2408             : 
    2409             :   virtual bool ClearsBackground() const
    2410             :   {
    2411             :     return false;
    2412             :   }
    2413             : 
    2414             :   /**
    2415             :    * Returns true if all layers that can be active should be forced to be
    2416             :    * active. Requires setting the pref layers.force-active=true.
    2417             :    */
    2418             :   static bool ForceActiveLayers();
    2419             : 
    2420             :   /**
    2421             :    * @return LAYER_NONE if BuildLayer will return null. In this case
    2422             :    * there is no layer for the item, and Paint should be called instead
    2423             :    * to paint the content using Thebes.
    2424             :    * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
    2425             :    * not return null (unless there's an error) --- but the layer contents
    2426             :    * are not changing frequently. In this case it makes sense to composite
    2427             :    * the layer into a PaintedLayer with other content, so we don't have to
    2428             :    * recomposite it every time we paint.
    2429             :    * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
    2430             :    * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
    2431             :    * all descendant display item frames must have an active scrolled root
    2432             :    * that's either the same as this item's frame's active scrolled root, or
    2433             :    * a descendant of this item's frame. This ensures that the entire
    2434             :    * set of display items can be collapsed onto a single PaintedLayer.
    2435             :    * Return LAYER_ACTIVE if the layer is active, that is, its contents are
    2436           0 :    * changing frequently. In this case it makes sense to keep the layer
    2437             :    * as a separate buffer in VRAM and composite it into the destination
    2438             :    * every time we paint.
    2439             :    *
    2440           0 :    * Users of GetLayerState should check ForceActiveLayers() and if it returns
    2441             :    * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE.
    2442             :    */
    2443             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    2444             :                                    LayerManager* aManager,
    2445             :                                    const ContainerLayerParameters& aParameters)
    2446             :   {
    2447           0 :     return mozilla::LAYER_NONE;
    2448             :   }
    2449           0 : 
    2450             :   /**
    2451             :    * Return true to indicate the layer should be constructed even if it's
    2452             :    * completely invisible.
    2453             :    */
    2454             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const
    2455             :   {
    2456             :     return false;
    2457           0 :   }
    2458             : 
    2459             :   /**
    2460             :    * Actually paint this item to some rendering context.
    2461             :    * Content outside mVisibleRect need not be painted.
    2462             :    * aCtx must be set up as for nsDisplayList::Paint.
    2463             :    */
    2464             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {}
    2465             : 
    2466             : #ifdef MOZ_DUMP_PAINTING
    2467             :   /**
    2468             :    * Mark this display item as being painted via FrameLayerBuilder::DrawPaintedLayer.
    2469             :    */
    2470             :   bool Painted() const { return mPainted; }
    2471             : 
    2472             :   /**
    2473             :    * Check if this display item has been painted.
    2474             :    */
    2475             :   void SetPainted() { mPainted = true; }
    2476             : #endif
    2477             : 
    2478             :   /**
    2479             :    * Get the layer drawn by this display item. Call this only if
    2480             :    * GetLayerState() returns something other than LAYER_NONE.
    2481             :    * If GetLayerState returned LAYER_NONE then Paint will be called
    2482             :    * instead.
    2483             :    * This is called while aManager is in the construction phase.
    2484             :    *
    2485           0 :    * The caller (nsDisplayList) is responsible for setting the visible
    2486             :    * region of the layer.
    2487             :    *
    2488             :    * @param aContainerParameters should be passed to
    2489           0 :    * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
    2490             :    * constructed.
    2491             :    */
    2492             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    2493             :                                              LayerManager* aManager,
    2494             :                                              const ContainerLayerParameters& aContainerParameters)
    2495             :   {
    2496             :     return nullptr;
    2497             :   }
    2498             : 
    2499             :   /**
    2500           0 :    * Function to create the WebRenderCommands.
    2501             :    * We should check if the layer state is
    2502             :    * active first and have an early return if the layer state is
    2503             :    * not active.
    2504           0 :    *
    2505             :    * @return true if successfully creating webrender commands.
    2506             :    */
    2507             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    2508             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    2509             :                                        const StackingContextHelper& aSc,
    2510             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    2511             :                                        nsDisplayListBuilder* aDisplayListBuilder) { return false; }
    2512             : 
    2513             :   /**
    2514             :    * Updates the provided aLayerData with any APZ-relevant scroll data
    2515             :    * that is specific to this display item. This is stuff that would normally
    2516             :    * be put on the layer during BuildLayer, but this is only called in
    2517             :    * layers-free webrender mode, where we don't have layers.
    2518             :    *
    2519             :    * This function returns true if and only if it has APZ-relevant scroll data
    2520             :    * to provide. Note that the arguments passed in may be nullptr, in which case
    2521           0 :    * the function should still return true if and only if it has APZ-relevant
    2522             :    * scroll data, but obviously in this case it can't actually put the
    2523           0 :    * data onto aLayerData, because there isn't one.
    2524             :    *
    2525             :    * This function assumes that aData and aLayerData will either both be null,
    2526             :    * or will both be non-null. The caller is responsible for enforcing this.
    2527             :    */
    2528             :   virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
    2529             :                                 mozilla::layers::WebRenderLayerScrollData* aLayerData)
    2530             :   { return false; }
    2531             : 
    2532             :   /**
    2533             :    * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
    2534             :    * which may be visible. If the display item opaquely covers an area, it
    2535             :    * can remove that area from aVisibleRegion before returning.
    2536             :    * nsDisplayList::ComputeVisibility automatically subtracts the region
    2537             :    * returned by GetOpaqueRegion, and automatically removes items whose bounds
    2538             :    * do not intersect the visible area, so implementations of
    2539             :    * nsDisplayItem::ComputeVisibility do not need to do these things.
    2540             :    * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
    2541             :    * this item to the intersection of *aVisibleRegion and this item's bounds.
    2542             :    * We rely on that, so this should only be called by
    2543             :    * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
    2544             :    * aAllowVisibleRegionExpansion is a rect where we are allowed to
    2545             :    * expand the visible region and is only used for making sure the
    2546             :    * background behind a plugin is visible.
    2547             :    * This method needs to be idempotent.
    2548             :    *
    2549             :    * @return true if the item is visible, false if no part of the item
    2550             :    * is visible.
    2551             :    */
    2552           0 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    2553             :                                  nsRegion* aVisibleRegion);
    2554             : 
    2555             :   /**
    2556             :    * Checks if the given display item can be merged with this item.
    2557             :    * @return true if the merging is possible, otherwise false.
    2558             :    */
    2559             :   virtual bool CanMerge(const nsDisplayItem* aItem) const { return false; }
    2560             : 
    2561             :   /**
    2562           0 :    * Try to merge with the other item (which is below us in the display
    2563             :    * list). This gets used by nsDisplayClip to coalesce clipping operations
    2564             :    * (optimization), by nsDisplayOpacity to merge rendering for the same
    2565             :    * content element into a single opacity group (correctness), and will be
    2566             :    * used by nsDisplayOutline to merge multiple outlines for the same element
    2567           0 :    * (also for correctness).
    2568           0 :    */
    2569             :   virtual void Merge(const nsDisplayItem* aItem) {}
    2570             : 
    2571             :   /**
    2572             :    * Merges the given display list to this item.
    2573             :    */
    2574             :   virtual void MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
    2575           0 :                                         const nsDisplayItem* aItem) {}
    2576             : 
    2577           0 :   /**
    2578             :    * Appends the underlying frames of all display items that have been
    2579             :    * merged into this one (excluding  this item's own underlying frame)
    2580             :    * to aFrames.
    2581             :    */
    2582             :   virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) const {}
    2583             : 
    2584             :   virtual bool HasMergedFrames() const { return false; }
    2585           0 : 
    2586           0 :   /**
    2587             :    * During the visibility computation and after TryMerge, display lists may
    2588             :    * return true here to flatten themselves away, removing them. This
    2589             :    * flattening is distinctly different from FlattenTo, which occurs before
    2590             :    * items are merged together.
    2591             :    */
    2592             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
    2593             :     return false;
    2594           0 :   }
    2595             : 
    2596             :   /**
    2597             :    * Some items such as those calling into the native themed widget machinery
    2598             :    * have to be painted on the content process. In this case it is best to avoid
    2599             :    * allocating layers that serializes and forwards the work to the compositor.
    2600             :    */
    2601           0 :   virtual bool MustPaintOnContentSide() const { return false; }
    2602             : 
    2603           0 :   /**
    2604             :    * If this has a child list where the children are in the same coordinate
    2605             :    * system as this item (i.e., they have the same reference frame),
    2606           0 :    * return the list.
    2607             :    */
    2608             :   virtual nsDisplayList* GetSameCoordinateSystemChildren() const
    2609             :   {
    2610             :     return nullptr;
    2611             :   }
    2612             : 
    2613             :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {}
    2614             :   /**
    2615             :    * Do UpdateBounds() for items with frames establishing or extending
    2616             :    * 3D rendering context.
    2617             :    *
    2618             :    * This function is called by UpdateBoundsFor3D() of
    2619             :    * nsDisplayTransform(), and it is called by
    2620             :    * BuildDisplayListForStackingContext() on transform items
    2621           0 :    * establishing 3D rendering context.
    2622             :    *
    2623             :    * The bounds of a transform item with the frame establishing 3D
    2624             :    * rendering context should be computed by calling
    2625             :    * DoUpdateBoundsPreserves3D() on all descendants that participate
    2626             :    * the same 3d rendering context.
    2627           0 :    */
    2628             :   virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) {}
    2629             : 
    2630             :   /**
    2631             :    * If this has a child list, return it, even if the children are in
    2632             :    * a different coordinate system to this item.
    2633           0 :    */
    2634             :   virtual RetainedDisplayList* GetChildren() const { return nullptr; }
    2635           0 : 
    2636             :   /**
    2637           0 :    * Returns the building rectangle used by nsDisplayListBuilder when
    2638           0 :    * this item was constructed.
    2639             :    */
    2640             :   const nsRect& GetBuildingRect() const { return mBuildingRect; }
    2641           0 : 
    2642           0 :   void SetBuildingRect(const nsRect& aBuildingRect)
    2643             :   {
    2644             :     mPaintRect = mBuildingRect = aBuildingRect;
    2645             :   }
    2646             : 
    2647             :   void SetPaintRect(const nsRect& aPaintRect) {
    2648             :     mPaintRect = aPaintRect;
    2649             :     mPaintRectValid = true;
    2650             :   }
    2651             :   bool HasPaintRect() const { return mPaintRectValid; }
    2652           0 : 
    2653             :   /**
    2654             :    * Returns the building rect for the children, relative to their
    2655             :    * reference frame. Can be different from mBuildingRect for nsDisplayTransform,
    2656             :    * since the reference frame for the children is different from the reference
    2657             :    * frame for the item itself.
    2658           0 :    */
    2659             :   virtual const nsRect& GetBuildingRectForChildren() const { return mBuildingRect; }
    2660             : 
    2661           0 :   /**
    2662           0 :    * Stores the given opacity value to be applied when drawing. It is an error to
    2663             :    * call this if CanApplyOpacity returned false.
    2664             :    */
    2665             :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    2666             :                             float aOpacity,
    2667           0 :                             const DisplayItemClipChain* aClip) {
    2668             :     NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity not supported on this type");
    2669             :   }
    2670             :   /**
    2671             :    * Returns true if this display item would return true from ApplyOpacity without
    2672             :    * actually applying the opacity. Otherwise returns false.
    2673             :    */
    2674             :   virtual bool CanApplyOpacity() const { return false; }
    2675             : 
    2676           0 :   bool ForceNotVisible() const { return mForceNotVisible; }
    2677             : 
    2678             :   /**
    2679             :    * For debugging and stuff
    2680             :    */
    2681             :   virtual const char* Name() const = 0;
    2682             : 
    2683             :   virtual void WriteDebugInfo(std::stringstream& aStream) {}
    2684             : 
    2685             :   nsDisplayItem* GetAbove() { return mAbove; }
    2686             : 
    2687             :   /**
    2688             :    * Like ComputeVisibility, but does the work that nsDisplayList
    2689             :    * does per-item:
    2690             :    * -- Intersects GetBounds with aVisibleRegion and puts the result
    2691             :    * in mVisibleRect
    2692             :    * -- Subtracts bounds from aVisibleRegion if the item is opaque
    2693             :    */
    2694           0 :   bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
    2695           0 :                            nsRegion* aVisibleRegion,
    2696           0 :                            bool aUseClipBounds = true);
    2697             : 
    2698             :   /**
    2699             :    * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
    2700             :    */
    2701             :   const nsPoint& ToReferenceFrame() const {
    2702             :     NS_ASSERTION(mFrame, "No frame?");
    2703             :     return mToReferenceFrame;
    2704             :   }
    2705             :   /**
    2706             :    * @return the root of the display list's frame (sub)tree, whose origin
    2707           0 :    * establishes the coordinate system for the display list
    2708             :    */
    2709           0 :   const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
    2710           0 : 
    2711           0 :   /**
    2712             :    * Returns the reference frame for display item children of this item.
    2713             :    */
    2714           0 :   virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
    2715           0 : 
    2716             :   AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
    2717             :     MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
    2718             :     return mAnimatedGeometryRoot;
    2719             :   }
    2720             : 
    2721             :   virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const {
    2722             :     return GetAnimatedGeometryRoot();
    2723             :   }
    2724           0 : 
    2725             :   /**
    2726           0 :    * Checks if this display item (or any children) contains content that might
    2727             :    * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
    2728             :    * bounds of the area that needs component alpha, or an empty rect if nothing
    2729             :    * in the item does.
    2730             :    */
    2731             :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const
    2732             :   {
    2733             :     return nsRect();
    2734             :   }
    2735             : 
    2736             :   /**
    2737             :    * Disable usage of component alpha. Currently only relevant for items that have text.
    2738             :    */
    2739             :   void DisableComponentAlpha()
    2740             :   {
    2741             :     mDisableSubpixelAA = true;
    2742           0 :   }
    2743           0 : 
    2744             :   bool IsSubpixelAADisabled() const { return mDisableSubpixelAA; }
    2745             : 
    2746           0 :   /**
    2747             :    * Check if we can add async animations to the layer for this display item.
    2748           0 :    */
    2749             :   virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
    2750           0 :     return false;
    2751             :   }
    2752             : 
    2753             :   virtual bool SupportsOptimizingToImage() const { return false; }
    2754           0 : 
    2755           0 :   const DisplayItemClip& GetClip() const
    2756             :   {
    2757             :     return mClip ? *mClip : DisplayItemClip::NoClip();
    2758             :   }
    2759           0 :   void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther, bool aStore);
    2760             : 
    2761             :   virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; }
    2762             :   const ActiveScrolledRoot* GetActiveScrolledRoot() const { return mActiveScrolledRoot; }
    2763             : 
    2764             :   virtual void SetClipChain(const DisplayItemClipChain* aClipChain,
    2765             :                             bool aStore);
    2766             :   const DisplayItemClipChain* GetClipChain() const { return mClipChain; }
    2767             : 
    2768           0 :   /**
    2769             :    * Intersect all clips in our clip chain up to (and including) aASR and set
    2770             :    * set the intersection as this item's clip.
    2771             :    */
    2772             :   void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
    2773             :                          const ActiveScrolledRoot* aASR);
    2774             : 
    2775           0 :   bool BackfaceIsHidden() const { return mFrame->BackfaceIsHidden(); }
    2776             : 
    2777           0 :   bool In3DContextAndBackfaceIsHidden()
    2778           0 :   {
    2779             :     return mBackfaceHidden;
    2780             :   }
    2781           0 : 
    2782             :   bool HasSameTypeAndClip(const nsDisplayItem* aOther) const
    2783           0 :   {
    2784             :     return GetType() == aOther->GetType() &&
    2785             :            GetClipChain() == aOther->GetClipChain();
    2786             :   }
    2787             : 
    2788             :   bool HasSameContent(const nsDisplayItem* aOther) const
    2789             :   {
    2790             :     return mFrame->GetContent() == aOther->Frame()->GetContent();
    2791             :   }
    2792             : 
    2793             :   bool IsReused() const
    2794             :   {
    2795             :     return mReusedItem;
    2796           0 :   }
    2797             : 
    2798           0 :   void SetReused(bool aReused)
    2799             :   {
    2800           0 :     mReusedItem = aReused;
    2801             :   }
    2802             : 
    2803             :   virtual bool CanBeReused() const { return true; }
    2804             : 
    2805             :   virtual nsIFrame* GetDependentFrame()
    2806             :   {
    2807             :     return nullptr;
    2808           0 :   }
    2809             : 
    2810             :   virtual mozilla::Maybe<nsRect> GetClipWithRespectToASR(
    2811             :       nsDisplayListBuilder* aBuilder,
    2812             :       const ActiveScrolledRoot* aASR) const;
    2813             : 
    2814             :   void SetDisplayItemData(mozilla::DisplayItemData* aDID) {
    2815             :     mDisplayItemData = aDID;
    2816             :   }
    2817             : 
    2818             :   mozilla::DisplayItemData* GetDisplayItemData() { return mDisplayItemData; }
    2819             : 
    2820             :   // Set the nsDisplayList that this item belongs to, and what
    2821             :   // index it is within that list. Temporary state for merging
    2822             :   // used by RetainedDisplayListBuilder.
    2823             :   void SetOldListIndex(nsDisplayList* aList, OldListIndex aIndex, uint32_t aListKey, uint32_t aNestingDepth)
    2824             :   {
    2825             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    2826             :     mOldListKey = aListKey;
    2827             :     mOldNestingDepth = aNestingDepth;
    2828             : #endif
    2829             :     mOldList = reinterpret_cast<uintptr_t>(aList);
    2830             :     mOldListIndex = aIndex;
    2831             :   }
    2832             :   bool GetOldListIndex(nsDisplayList* aList, uint32_t aListKey, OldListIndex* aOutIndex)
    2833             :   {
    2834             :     if (mOldList != reinterpret_cast<uintptr_t>(aList)) {
    2835             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    2836             :       MOZ_CRASH_UNSAFE_PRINTF("Item found was in the wrong list! type %d (outer type was %d at depth %d, now is %d)", GetPerFrameKey(), mOldListKey, mOldNestingDepth, aListKey);
    2837             : #endif
    2838           0 :       return false;
    2839             :     }
    2840             :     *aOutIndex = mOldListIndex;
    2841             :     return true;
    2842             :   }
    2843             : 
    2844             :   const nsRect& GetPaintRect() const {
    2845             :     return mPaintRect;
    2846             :   }
    2847             : 
    2848             : protected:
    2849             :   nsDisplayItem() = delete;
    2850             : 
    2851             :   typedef bool (*PrefFunc)(void);
    2852             :   bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
    2853             :   bool CanUseAdvancedLayer(LayerManager* aManager) const;
    2854             : 
    2855             :   nsIFrame* mFrame;
    2856             :   RefPtr<const DisplayItemClipChain> mClipChain;
    2857             :   const DisplayItemClip* mClip;
    2858             :   RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
    2859             :   // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
    2860             :   const nsIFrame* mReferenceFrame;
    2861             :   RefPtr<struct AnimatedGeometryRoot> mAnimatedGeometryRoot;
    2862             :   // Result of ToReferenceFrame(mFrame), if mFrame is non-null
    2863             :   nsPoint   mToReferenceFrame;
    2864             :   RefPtr<mozilla::DisplayItemData> mDisplayItemData;
    2865             : 
    2866             : private:
    2867             :   // This is the rectangle that nsDisplayListBuilder was using as the visible
    2868             :   // rect to decide which items to construct.
    2869             :   nsRect    mBuildingRect;
    2870             : 
    2871             :   // nsDisplayList::ComputeVisibility sets this to the visible region
    2872             :   // of the item by intersecting the visible region with the bounds
    2873             :   // of the item. Paint implementations can use this to limit their drawing.
    2874             :   // Guaranteed to be contained in GetBounds().
    2875             :   nsRect    mPaintRect;
    2876             : 
    2877             : protected:
    2878             : 
    2879             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    2880             : public:
    2881             :   uint32_t mOldListKey = 0;
    2882             :   uint32_t mOldNestingDepth = 0;
    2883             :   bool mMergedItem = false;
    2884             :   bool mPreProcessedItem = false;
    2885             : protected:
    2886             : #endif
    2887             :   OldListIndex mOldListIndex;
    2888             :   uintptr_t mOldList = 0;
    2889             : 
    2890             :   bool      mForceNotVisible;
    2891             :   bool      mDisableSubpixelAA;
    2892             :   bool      mReusedItem;
    2893           0 :   bool      mBackfaceHidden;
    2894             :   bool      mPaintRectValid;
    2895             : #ifdef MOZ_DUMP_PAINTING
    2896             :   // True if this frame has been painted.
    2897             :   bool      mPainted;
    2898             : #endif
    2899             : 
    2900             :   struct {
    2901             :     RefPtr<const DisplayItemClipChain> mClipChain;
    2902             :     const DisplayItemClip* mClip;
    2903             :   } mState;
    2904             : };
    2905             : 
    2906             : /**
    2907             :  * Manages a singly-linked list of display list items.
    2908             :  *
    2909             :  * mSentinel is the sentinel list value, the first value in the null-terminated
    2910             :  * linked list of items. mTop is the last item in the list (whose 'above'
    2911             :  * pointer is null). This class has no virtual methods. So list objects are just
    2912             :  * two pointers.
    2913             :  *
    2914             :  * Stepping upward through this list is very fast. Stepping downward is very
    2915             :  * slow so we don't support it. The methods that need to step downward
    2916             :  * (HitTest(), ComputeVisibility()) internally build a temporary array of all
    2917             :  * the items while they do the downward traversal, so overall they're still
    2918             :  * linear time. We have optimized for efficient AppendToTop() of both
    2919             :  * items and lists, with minimal codesize. AppendToBottom() is efficient too.
    2920             :  */
    2921             : class nsDisplayList {
    2922             : public:
    2923             :   typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
    2924           0 :   typedef mozilla::layers::Layer Layer;
    2925           0 :   typedef mozilla::layers::LayerManager LayerManager;
    2926             :   typedef mozilla::layers::PaintedLayer PaintedLayer;
    2927           0 : 
    2928             :   /**
    2929           0 :    * Create an empty list.
    2930             :    */
    2931           0 :   nsDisplayList()
    2932             :     : mLength(0)
    2933             :     , mIsOpaque(false)
    2934             :     , mForceTransparentSurface(false)
    2935             :   {
    2936             :     mTop = &mSentinel;
    2937             :     mSentinel.mAbove = nullptr;
    2938             :   }
    2939             :   ~nsDisplayList() {
    2940             :     if (mSentinel.mAbove) {
    2941             :       NS_WARNING("Nonempty list left over?");
    2942           0 :     }
    2943           0 :   }
    2944           0 : 
    2945           0 :   /**
    2946           0 :    * Append an item to the top of the list. The item must not currently
    2947           0 :    * be in a list and cannot be null.
    2948           0 :    */
    2949             :   void AppendToTop(nsDisplayItem* aItem) {
    2950             :     MOZ_ASSERT(aItem, "No item to append!");
    2951             :     MOZ_ASSERT(!aItem->mAbove, "Already in a list!");
    2952             :     mTop->mAbove = aItem;
    2953             :     mTop = aItem;
    2954             :     mLength++;
    2955             :   }
    2956             : 
    2957             :   /**
    2958             :    * Append a new item to the bottom of the list. The item must be non-null
    2959             :    * and not already in a list.
    2960             :    */
    2961             :   void AppendToBottom(nsDisplayItem* aItem) {
    2962             :     MOZ_ASSERT(aItem, "No item to append!");
    2963             :     MOZ_ASSERT(!aItem->mAbove, "Already in a list!");
    2964             :     aItem->mAbove = mSentinel.mAbove;
    2965             :     mSentinel.mAbove = aItem;
    2966             :     if (mTop == &mSentinel) {
    2967             :       mTop = aItem;
    2968             :     }
    2969             :     mLength++;
    2970             :   }
    2971             : 
    2972             :   /**
    2973             :    * Removes all items from aList and appends them to the top of this list
    2974             :    */
    2975             :   void AppendToTop(nsDisplayList* aList) {
    2976             :     if (aList->mSentinel.mAbove) {
    2977             :       mTop->mAbove = aList->mSentinel.mAbove;
    2978             :       mTop = aList->mTop;
    2979             :       aList->mTop = &aList->mSentinel;
    2980             :       aList->mSentinel.mAbove = nullptr;
    2981             :       mLength += aList->mLength;
    2982             :       aList->mLength = 0;
    2983             :     }
    2984             :   }
    2985             : 
    2986             :   /**
    2987             :    * Removes all items from aList and prepends them to the bottom of this list
    2988             :    */
    2989             :   void AppendToBottom(nsDisplayList* aList) {
    2990             :     if (aList->mSentinel.mAbove) {
    2991             :       aList->mTop->mAbove = mSentinel.mAbove;
    2992             :       mSentinel.mAbove = aList->mSentinel.mAbove;
    2993             :       if (mTop == &mSentinel) {
    2994             :         mTop = aList->mTop;
    2995             :       }
    2996             : 
    2997             :       aList->mTop = &aList->mSentinel;
    2998             :       aList->mSentinel.mAbove = nullptr;
    2999             :       mLength += aList->mLength;
    3000             :       aList->mLength = 0;
    3001             :     }
    3002             :   }
    3003             : 
    3004             :   /**
    3005             :    * Remove an item from the bottom of the list and return it.
    3006             :    */
    3007             :   nsDisplayItem* RemoveBottom();
    3008             : 
    3009             :   /**
    3010           0 :    * Remove all items from the list and call their destructors.
    3011           0 :    */
    3012             :   void DeleteAll(nsDisplayListBuilder* aBuilder);
    3013             : 
    3014             :   /**
    3015             :    * @return the item at the top of the list, or null if the list is empty
    3016             :    */
    3017           0 :   nsDisplayItem* GetTop() const {
    3018             :     return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr;
    3019             :   }
    3020             :   /**
    3021             :    * @return the item at the bottom of the list, or null if the list is empty
    3022             :    */
    3023             :   nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
    3024             :   bool IsEmpty() const { return mTop == &mSentinel; }
    3025             : 
    3026             :   /**
    3027             :    * @return the number of items in the list
    3028             :    */
    3029             :   uint32_t Count() const { return mLength; }
    3030             :   /**
    3031             :    * Stable sort the list by the z-order of GetUnderlyingFrame() on
    3032             :    * each item. 'auto' is counted as zero.
    3033             :    * It is assumed that the list is already in content document order.
    3034             :    */
    3035             :   void SortByZOrder();
    3036             :   /**
    3037             :    * Stable sort the list by the tree order of the content of
    3038             :    * GetUnderlyingFrame() on each item. z-index is ignored.
    3039             :    * @param aCommonAncestor a common ancestor of all the content elements
    3040             :    * associated with the display items, for speeding up tree order
    3041             :    * checks, or nullptr if not known; it's only a hint, if it is not an
    3042             :    * ancestor of some elements, then we lose performance but not correctness
    3043             :    */
    3044             :   void SortByContentOrder(nsIContent* aCommonAncestor);
    3045             : 
    3046             :   /**
    3047             :    * Sort the display list using a stable sort. Take care, because some of the
    3048             :    * items might be nsDisplayLists themselves.
    3049             :    * aComparator(Item item1, Item item2) should return true if item1 should go
    3050             :    * before item2.
    3051             :    * We sort the items into increasing order.
    3052             :    */
    3053             :   template<typename Item, typename Comparator>
    3054             :   void Sort(const Comparator& aComparator) {
    3055             :     // Some casual local browsing testing suggests that a local preallocated
    3056             :     // array of 20 items should be able to avoid a lot of dynamic allocations
    3057             :     // here.
    3058             :     AutoTArray<Item, 20> items;
    3059             : 
    3060             :     while (nsDisplayItem* item = RemoveBottom()) {
    3061             :       items.AppendElement(Item(item));
    3062             :     }
    3063             : 
    3064             :     std::stable_sort(items.begin(), items.end(), aComparator);
    3065             : 
    3066             :     for (Item& item : items) {
    3067             :       AppendToTop(item);
    3068             :     }
    3069             :   }
    3070             : 
    3071             :   /**
    3072             :    * Compute visiblity for the items in the list.
    3073             :    * We put this logic here so it can be shared by top-level
    3074             :    * painting and also display items that maintain child lists.
    3075             :    * This is also a good place to put ComputeVisibility-related logic
    3076             :    * that must be applied to every display item. In particular, this
    3077             :    * sets mVisibleRect on each display item.
    3078             :    * This sets mIsOpaque if the entire visible area of this list has
    3079             :    * been removed from aVisibleRegion when we return.
    3080             :    * This does not remove any items from the list, so we can recompute
    3081             :    * visiblity with different regions later (see
    3082             :    * FrameLayerBuilder::DrawPaintedLayer).
    3083             :    * This method needs to be idempotent.
    3084             :    *
    3085             :    * @param aVisibleRegion the area that is visible, relative to the
    3086             :    * reference frame; on return, this contains the area visible under the list.
    3087             :    * I.e., opaque contents of this list are subtracted from aVisibleRegion.
    3088             :    * @param aListVisibleBounds must be equal to the bounds of the intersection
    3089             :    * of aVisibleRegion and GetBounds() for this list.
    3090             :    * @return true if any item in the list is visible.
    3091             :    */
    3092             :   bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
    3093             :                                    nsRegion* aVisibleRegion,
    3094             :                                    const nsRect& aListVisibleBounds);
    3095             : 
    3096             :   /**
    3097             :    * As ComputeVisibilityForSublist, but computes visibility for a root
    3098             :    * list (a list that does not belong to an nsDisplayItem).
    3099             :    * This method needs to be idempotent.
    3100             :    *
    3101             :    * @param aVisibleRegion the area that is visible
    3102             :    */
    3103             :   bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
    3104             :                                 nsRegion* aVisibleRegion);
    3105             : 
    3106             :   /**
    3107             :    * Returns true if the visible region output from ComputeVisiblity was
    3108             :    * empty, i.e. everything visible in this list is opaque.
    3109             :    */
    3110             :   bool IsOpaque() const {
    3111             :     return mIsOpaque;
    3112             :   }
    3113             : 
    3114             :   /**
    3115             :    * Returns true if any display item requires the surface to be transparent.
    3116             :    */
    3117             :   bool NeedsTransparentSurface() const {
    3118             :     return mForceTransparentSurface;
    3119             :   }
    3120             :   /**
    3121             :    * Paint the list to the rendering context. We assume that (0,0) in aCtx
    3122             :    * corresponds to the origin of the reference frame. For best results,
    3123             :    * aCtx's current transform should make (0,0) pixel-aligned. The
    3124             :    * rectangle in aDirtyRect is painted, which *must* be contained in the
    3125             :    * dirty rect used to construct the display list.
    3126             :    *
    3127             :    * If aFlags contains PAINT_USE_WIDGET_LAYERS and
    3128             :    * ShouldUseWidgetLayerManager() is set, then we will paint using
    3129             :    * the reference frame's widget's layer manager (and ctx may be null),
    3130             :    * otherwise we will use a temporary BasicLayerManager and ctx must
    3131             :    * not be null.
    3132             :    *
    3133             :    * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
    3134             :    * layer manager has already had BeginTransaction() called on it and
    3135             :    * we should not call it again.
    3136             :    *
    3137             :    * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode
    3138             :    * to avoid short cut optimizations.
    3139             :    *
    3140             :    * This must only be called on the root display list of the display list
    3141             :    * tree.
    3142             :    *
    3143             :    * We return the layer manager used for painting --- mainly so that
    3144             :    * callers can dump its layer tree if necessary.
    3145             :    */
    3146             :   enum {
    3147             :     PAINT_DEFAULT = 0,
    3148             :     PAINT_USE_WIDGET_LAYERS = 0x01,
    3149             :     PAINT_EXISTING_TRANSACTION = 0x04,
    3150             :     PAINT_NO_COMPOSITE = 0x08,
    3151             :     PAINT_COMPRESSED = 0x10,
    3152             :     PAINT_IDENTICAL_DISPLAY_LIST = 0x20
    3153             :   };
    3154             :   already_AddRefed<LayerManager> PaintRoot(nsDisplayListBuilder* aBuilder,
    3155             :                                            gfxContext* aCtx,
    3156             :                                            uint32_t aFlags);
    3157             : 
    3158             :   mozilla::FrameLayerBuilder* BuildLayers(nsDisplayListBuilder* aBuilder,
    3159             :                                           LayerManager* aLayerManager,
    3160             :                                           uint32_t aFlags,
    3161             :                                           bool aIsWidgetTransaction);
    3162             :   /**
    3163             :    * Get the bounds. Takes the union of the bounds of all children.
    3164             :    * The result is not cached.
    3165             :    */
    3166             :   nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
    3167             : 
    3168             :   /**
    3169             :    * Get this list's bounds, respecting clips relative to aASR. The result is
    3170             :    * the union of each item's clipped bounds with respect to aASR. That means
    3171             :    * that if an item can move asynchronously with an ASR that is a descendant
    3172             :    * of aASR, then the clipped bounds with respect to aASR will be the clip of
    3173             :    * that item for aASR, because the item can move anywhere inside that clip.
    3174             :    * If there is an item in this list which is not bounded with respect to
    3175             :    * aASR (i.e. which does not have "finite bounds" with respect to aASR),
    3176             :    * then this method trigger an assertion failure.
    3177             :    * The optional aBuildingRect out argument can be set to non-null if the
    3178             :    * caller is also interested to know the building rect.  This can be used
    3179             :    * to get the visible rect efficiently without traversing the display list
    3180             :    * twice.
    3181             :    */
    3182             :   nsRect GetClippedBoundsWithRespectToASR(nsDisplayListBuilder* aBuilder,
    3183             :                                           const ActiveScrolledRoot* aASR,
    3184             :                                           nsRect* aBuildingRect = nullptr) const;
    3185             : 
    3186             :   /**
    3187             :    * Find the topmost display item that returns a non-null frame, and return
    3188             :    * the frame.
    3189             :    */
    3190             :   void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    3191             :                nsDisplayItem::HitTestState* aState,
    3192             :                nsTArray<nsIFrame*> *aOutFrames) const;
    3193             :   /**
    3194             :    * Compute the union of the visible rects of the items in the list. The
    3195             :    * result is not cached.
    3196             :    */
    3197             :   nsRect GetBuildingRect() const;
    3198             : 
    3199             :   void SetIsOpaque()
    3200             :   {
    3201             :     mIsOpaque = true;
    3202             :   }
    3203             :   void SetNeedsTransparentSurface()
    3204             :   {
    3205             :     mForceTransparentSurface = true;
    3206             :   }
    3207             : 
    3208             :   void RestoreState() {
    3209             :     mIsOpaque = false;
    3210             :     mForceTransparentSurface = false;
    3211             :   }
    3212             : 
    3213             : private:
    3214             :   nsDisplayItemLink  mSentinel;
    3215             :   nsDisplayItemLink* mTop;
    3216             : 
    3217             :   uint32_t mLength;
    3218             : 
    3219             :   // This is set to true by FrameLayerBuilder if the final visible region
    3220             :   // is empty (i.e. everything that was visible is covered by some
    3221             :   // opaque content in this list).
    3222             :   bool mIsOpaque;
    3223             :   // This is set to true by FrameLayerBuilder if any display item in this
    3224           0 :   // list needs to force the surface containing this list to be transparent.
    3225             :   bool mForceTransparentSurface;
    3226             : };
    3227           0 : 
    3228           0 : class FlattenedDisplayItemIterator
    3229             : {
    3230           0 : public:
    3231             :   FlattenedDisplayItemIterator(nsDisplayListBuilder* aBuilder,
    3232             :                                nsDisplayList* aList,
    3233           0 :                                const bool aResolveFlattening = true)
    3234             :     : mBuilder(aBuilder)
    3235           0 :     , mNext(aList->GetBottom())
    3236             :   {
    3237           2 :     if (aResolveFlattening) {
    3238           2 :       // This is done conditionally in case subclass overrides
    3239           2 :       // ShouldFlattenNextItem().
    3240           2 :       ResolveFlattening();
    3241             :     }
    3242           0 :   }
    3243             : 
    3244           0 :   virtual ~FlattenedDisplayItemIterator()
    3245             :   {
    3246             :     MOZ_ASSERT(!HasNext());
    3247           0 :   }
    3248           0 : 
    3249           0 :   nsDisplayItem* GetNext()
    3250             :   {
    3251           0 :     nsDisplayItem* next = mNext;
    3252             : 
    3253             :     // Advance mNext to the following item
    3254           2 :     if (next) {
    3255             :       mNext = mNext->GetAbove();
    3256           0 :       ResolveFlattening();
    3257             :     }
    3258             :     return next;
    3259             :   }
    3260             : 
    3261             :   bool HasNext() const
    3262             :   {
    3263             :     return mNext || !mStack.IsEmpty();
    3264             :   }
    3265           2 : 
    3266             :   nsDisplayItem* PeekNext()
    3267           2 :   {
    3268             :     return mNext;
    3269             :   }
    3270           0 : 
    3271             : protected:
    3272           0 :   bool AtEndOfNestedList() const
    3273             :   {
    3274             :     return !mNext && mStack.Length() > 0;
    3275           2 :   }
    3276             : 
    3277             :   virtual bool ShouldFlattenNextItem()
    3278             :   {
    3279             :     return mNext && mNext->ShouldFlattenAway(mBuilder);
    3280           2 :   }
    3281           2 : 
    3282             :   void ResolveFlattening()
    3283           2 :   {
    3284           2 :     // Handle the case where we reach the end of a nested list, or the current
    3285           2 :     // item should start a new nested list. Repeat this until we find an actual
    3286             :     // item, or the very end of the outer list.
    3287           2 :     while (AtEndOfNestedList() || ShouldFlattenNextItem()) {
    3288             :       if (AtEndOfNestedList()) {
    3289             :         // Pop the last item off the stack.
    3290             :         mNext = mStack.LastElement();
    3291           2 :         EndNested(mNext);
    3292           2 :         mStack.RemoveElementAt(mStack.Length() - 1);
    3293           2 :         // We stored the item that was flattened, so advance to the next.
    3294           2 :         mNext = mNext->GetAbove();
    3295             :       } else {
    3296             :         // This item wants to be flattened. Store the current item on the stack,
    3297           2 :         // and use the first item in the child list instead.
    3298             :         mStack.AppendElement(mNext);
    3299           0 :         StartNested(mNext);
    3300           0 :         nsDisplayList* childItems = mNext->GetSameCoordinateSystemChildren();
    3301             :         mNext = childItems->GetBottom();
    3302             :       }
    3303             :     }
    3304             :   }
    3305             : 
    3306             :   virtual void EndNested(nsDisplayItem* aItem) {}
    3307             :   virtual void StartNested(nsDisplayItem* aItem) {}
    3308             : 
    3309             :   nsDisplayListBuilder* mBuilder;
    3310             :   nsDisplayItem* mNext;
    3311             :   AutoTArray<nsDisplayItem*, 10> mStack;
    3312             : };
    3313             : 
    3314             : /**
    3315             :  * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
    3316             :  * will put any generated items onto the appropriate list given here. It's
    3317             :  * basically just a collection with one list for each separate stacking layer.
    3318             :  * The lists themselves are external to this object and thus can be shared
    3319             :  * with others. Some of the list pointers may even refer to the same list.
    3320             :  */
    3321             : class nsDisplayListSet {
    3322             : public:
    3323             :   /**
    3324             :    * @return a list where one should place the border and/or background for
    3325             :    * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
    3326             :    */
    3327             :   nsDisplayList* BorderBackground() const { return mBorderBackground; }
    3328             :   /**
    3329             :    * @return a list where one should place the borders and/or backgrounds for
    3330             :    * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
    3331             :    */
    3332             :   nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; }
    3333             :   /**
    3334             :    * @return a list where one should place descendant floats (step 5 of
    3335             :    * CSS 2.1 appendix E)
    3336             :    */
    3337             :   nsDisplayList* Floats() const { return mFloats; }
    3338             :   /**
    3339             :    * @return a list where one should place the (pseudo) stacking contexts
    3340             :    * for descendants of this frame (everything from steps 3, 7 and 8
    3341             :    * of CSS 2.1 appendix E)
    3342             :    */
    3343             :   nsDisplayList* PositionedDescendants() const { return mPositioned; }
    3344             :   /**
    3345             :    * @return a list where one should place the outlines
    3346             :    * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
    3347             :    */
    3348             :   nsDisplayList* Outlines() const { return mOutlines; }
    3349             :   /**
    3350             :    * @return a list where one should place all other content
    3351             :    */
    3352             :   nsDisplayList* Content() const { return mContent; }
    3353             : 
    3354             :   void DeleteAll(nsDisplayListBuilder* aBuilder) {
    3355             :     BorderBackground()->DeleteAll(aBuilder);
    3356             :     BlockBorderBackgrounds()->DeleteAll(aBuilder);
    3357             :     Floats()->DeleteAll(aBuilder);
    3358             :     PositionedDescendants()->DeleteAll(aBuilder);
    3359             :     Outlines()->DeleteAll(aBuilder);
    3360             :     Content()->DeleteAll(aBuilder);
    3361             :   }
    3362             : 
    3363             :   nsDisplayListSet(nsDisplayList* aBorderBackground,
    3364             :                    nsDisplayList* aBlockBorderBackgrounds,
    3365             :                    nsDisplayList* aFloats,
    3366             :                    nsDisplayList* aContent,
    3367             :                    nsDisplayList* aPositionedDescendants,
    3368             :                    nsDisplayList* aOutlines) :
    3369             :      mBorderBackground(aBorderBackground),
    3370             :      mBlockBorderBackgrounds(aBlockBorderBackgrounds),
    3371             :      mFloats(aFloats),
    3372             :      mContent(aContent),
    3373             :      mPositioned(aPositionedDescendants),
    3374             :      mOutlines(aOutlines) {
    3375             :   }
    3376             : 
    3377             :   /**
    3378             :    * A copy constructor that lets the caller override the BorderBackground
    3379             :    * list.
    3380             :    */
    3381             :   nsDisplayListSet(const nsDisplayListSet& aLists,
    3382             :                    nsDisplayList* aBorderBackground) :
    3383             :      mBorderBackground(aBorderBackground),
    3384             :      mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),
    3385             :      mFloats(aLists.Floats()),
    3386             :      mContent(aLists.Content()),
    3387             :      mPositioned(aLists.PositionedDescendants()),
    3388             :      mOutlines(aLists.Outlines()) {
    3389             :   }
    3390             : 
    3391             :   /**
    3392             :    * Move all display items in our lists to top of the corresponding lists in the
    3393             :    * destination.
    3394             :    */
    3395             :   void MoveTo(const nsDisplayListSet& aDestination) const;
    3396             : 
    3397             : private:
    3398             :   // This class is only used on stack, so we don't have to worry about leaking
    3399             :   // it.  Don't let us be heap-allocated!
    3400             :   void* operator new(size_t sz) CPP_THROW_NEW;
    3401             : 
    3402             : protected:
    3403             :   nsDisplayList* mBorderBackground;
    3404             :   nsDisplayList* mBlockBorderBackgrounds;
    3405             :   nsDisplayList* mFloats;
    3406             :   nsDisplayList* mContent;
    3407             :   nsDisplayList* mPositioned;
    3408             :   nsDisplayList* mOutlines;
    3409             : };
    3410             : 
    3411             : /**
    3412             :  * A specialization of nsDisplayListSet where the lists are actually internal
    3413             :  * to the object, and all distinct.
    3414             :  */
    3415             : struct nsDisplayListCollection : public nsDisplayListSet {
    3416             :   explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder) :
    3417             :     nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    3418             :                      &mLists[5]) {}
    3419             :   explicit nsDisplayListCollection(nsDisplayListBuilder* aBuilder, nsDisplayList* aBorderBackground) :
    3420             :     nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
    3421             :                      &mLists[5]) {}
    3422             : 
    3423             :   /**
    3424             :    * Sort all lists by content order.
    3425             :    */
    3426             :   void SortAllByContentOrder(nsIContent* aCommonAncestor) {
    3427             :     for (int32_t i = 0; i < 6; ++i) {
    3428             :       mLists[i].SortByContentOrder(aCommonAncestor);
    3429             :     }
    3430             :   }
    3431             : 
    3432             : private:
    3433             :   // This class is only used on stack, so we don't have to worry about leaking
    3434             :   // it.  Don't let us be heap-allocated!
    3435             :   void* operator new(size_t sz) CPP_THROW_NEW;
    3436             : 
    3437             :   nsDisplayList mLists[6];
    3438             : };
    3439             : 
    3440             : /**
    3441             :  * A display list that also retains the partial build
    3442             :  * information (in the form of a DAG) used to create it.
    3443             :  *
    3444           0 :  * Display lists built from a partial list aren't necessarily
    3445             :  * in the same order as a full build, and the DAG retains
    3446             :  * the information needing to interpret the current
    3447             :  * order correctly.
    3448             :  */
    3449             : class RetainedDisplayList : public nsDisplayList {
    3450             : public:
    3451             :   RetainedDisplayList() {}
    3452             :   RetainedDisplayList(RetainedDisplayList&& aOther)
    3453             :   {
    3454             :     AppendToTop(&aOther);
    3455             :     mDAG = std::move(aOther.mDAG);
    3456             :   }
    3457             :   ~RetainedDisplayList()
    3458             :   {
    3459             :     MOZ_ASSERT(mOldItems.IsEmpty(), "Must empty list before destroying");
    3460             :   }
    3461             : 
    3462             :   RetainedDisplayList& operator=(RetainedDisplayList&& aOther)
    3463             :   {
    3464           0 :     MOZ_ASSERT(!Count(), "Can only move into an empty list!");
    3465             :     MOZ_ASSERT(mOldItems.IsEmpty(), "Can only move into an empty list!");
    3466           0 :     AppendToTop(&aOther);
    3467           0 :     mDAG = std::move(aOther.mDAG);
    3468           0 :     return *this;
    3469             :   }
    3470             : 
    3471           0 :   void DeleteAll(nsDisplayListBuilder* aBuilder)
    3472           0 :   {
    3473           0 :     for (OldItemInfo& i : mOldItems) {
    3474           0 :       if (i.mItem) {
    3475             :         i.mItem->Destroy(aBuilder);
    3476             :       }
    3477             :     }
    3478             :     mOldItems.Clear();
    3479             :     mDAG.Clear();
    3480             :     nsDisplayList::DeleteAll(aBuilder);
    3481             :   }
    3482             : 
    3483             :   DirectedAcyclicGraph<MergedListUnits> mDAG;
    3484             : 
    3485             :   // Temporary state initialized during the preprocess pass
    3486             :   // of RetainedDisplayListBuilder and then used during merging.
    3487             :   nsTArray<OldItemInfo> mOldItems;
    3488             : };
    3489             : 
    3490             : class nsDisplayImageContainer : public nsDisplayItem {
    3491             : public:
    3492             :   typedef mozilla::LayerIntPoint LayerIntPoint;
    3493             :   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
    3494             :   typedef mozilla::layers::ImageContainer ImageContainer;
    3495             :   typedef mozilla::layers::ImageLayer ImageLayer;
    3496             : 
    3497             :   nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    3498             :     : nsDisplayItem(aBuilder, aFrame)
    3499             :   {}
    3500             : 
    3501             :   /**
    3502             :    * @return true if this display item can be optimized into an image layer.
    3503             :    * It is an error to call GetContainer() unless you've called
    3504             :    * CanOptimizeToImageLayer() first and it returned true.
    3505             :    */
    3506             :   virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
    3507             :                                        nsDisplayListBuilder* aBuilder);
    3508             : 
    3509             :   already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
    3510             :                                                 nsDisplayListBuilder* aBuilder);
    3511             :   void ConfigureLayer(ImageLayer* aLayer,
    3512             :                       const ContainerLayerParameters& aParameters);
    3513             : 
    3514             :   virtual void UpdateDrawResult(mozilla::image::ImgDrawResult aResult) = 0;
    3515             : 
    3516             :   virtual already_AddRefed<imgIContainer> GetImage() = 0;
    3517             : 
    3518             :   virtual nsRect GetDestRect() const = 0;
    3519             : 
    3520             :   virtual bool SupportsOptimizingToImage() const override { return true; }
    3521             : };
    3522             : 
    3523             : /**
    3524             :  * Use this class to implement not-very-frequently-used display items
    3525             :  * that are not opaque, do not receive events, and are bounded by a frame's
    3526             :  * border-rect.
    3527             :  *
    3528             :  * This should not be used for display items which are created frequently,
    3529             :  * because each item is one or two pointers bigger than an item from a
    3530             :  * custom display item class could be, and fractionally slower. However it does
    3531             :  * save code size. We use this for infrequently-used item types.
    3532             :  */
    3533             : class nsDisplayGeneric : public nsDisplayItem {
    3534             : public:
    3535             :   typedef void (* PaintCallback)(nsIFrame* aFrame, DrawTarget* aDrawTarget,
    3536             :                                  const nsRect& aDirtyRect, nsPoint aFramePt);
    3537             : 
    3538             :   // XXX: should be removed eventually
    3539             :   typedef void (* OldPaintCallback)(nsIFrame* aFrame, gfxContext* aCtx,
    3540             :                                     const nsRect& aDirtyRect, nsPoint aFramePt);
    3541             : 
    3542             :   nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3543             :                    PaintCallback aPaint, const char* aName, DisplayItemType aType)
    3544             :     : nsDisplayItem(aBuilder, aFrame)
    3545             :     , mPaint(aPaint)
    3546             :     , mOldPaint(nullptr)
    3547             :     , mName(aName)
    3548             :     , mType(aType)
    3549             :   {
    3550             :     MOZ_COUNT_CTOR(nsDisplayGeneric);
    3551             :   }
    3552             : 
    3553             :   // XXX: should be removed eventually
    3554             :   nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3555             :                    OldPaintCallback aOldPaint, const char* aName, DisplayItemType aType)
    3556             :     : nsDisplayItem(aBuilder, aFrame)
    3557             :     , mPaint(nullptr)
    3558           0 :     , mOldPaint(aOldPaint)
    3559           0 :     , mName(aName)
    3560           0 :     , mType(aType)
    3561             :   {
    3562             :     MOZ_COUNT_CTOR(nsDisplayGeneric);
    3563           0 :   }
    3564             : #ifdef NS_BUILD_REFCNT_LOGGING
    3565           0 :   virtual ~nsDisplayGeneric() {
    3566           0 :     MOZ_COUNT_DTOR(nsDisplayGeneric);
    3567           0 :   }
    3568             : #endif
    3569           0 : 
    3570             :   virtual void Paint(nsDisplayListBuilder* aBuilder,
    3571           0 :                      gfxContext* aCtx) override {
    3572           0 :     MOZ_ASSERT(!!mPaint != !!mOldPaint);
    3573           0 :     if (mPaint) {
    3574             :       mPaint(mFrame, aCtx->GetDrawTarget(), GetPaintRect(), ToReferenceFrame());
    3575             :     } else {
    3576             :       mOldPaint(mFrame, aCtx, GetPaintRect(), ToReferenceFrame());
    3577           0 :     }
    3578             :   }
    3579           0 :   virtual const char* Name() const override { return mName; }
    3580           0 :   virtual DisplayItemType GetType() const override { return mType; }
    3581           0 : 
    3582             :   // This override is needed because GetType() for nsDisplayGeneric subclasses
    3583             :   // does not match TYPE_GENERIC that was used to allocate the object.
    3584             :   virtual void Destroy(nsDisplayListBuilder* aBuilder) override
    3585             :   {
    3586             :     this->~nsDisplayGeneric();
    3587             :     aBuilder->Destroy(DisplayItemType::TYPE_GENERIC, this);
    3588             :   }
    3589             : 
    3590             : protected:
    3591             :   void* operator new(size_t aSize,
    3592             :                      nsDisplayListBuilder* aBuilder) {
    3593             :     return aBuilder->Allocate(aSize, DisplayItemType::TYPE_GENERIC);
    3594             :   }
    3595             :   template<typename T, typename... Args>
    3596             :   friend T* MakeDisplayItem(nsDisplayListBuilder* aBuilder, Args&&... aArgs);
    3597             : 
    3598             :   PaintCallback mPaint;
    3599             :   OldPaintCallback mOldPaint;   // XXX: should be removed eventually
    3600             :   const char* mName;
    3601             :   DisplayItemType mType;
    3602             : };
    3603             : 
    3604             : #if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
    3605             : /**
    3606             :  * This class implements painting of reflow counts.  Ideally, we would simply
    3607             :  * make all the frame names be those returned by nsFrame::GetFrameName
    3608             :  * (except that tosses in the content tag name!)  and support only one color
    3609             :  * and eliminate this class altogether in favor of nsDisplayGeneric, but for
    3610             :  * the time being we can't pass args to a PaintCallback, so just have a
    3611             :  * separate class to do the right thing.  Sadly, this alsmo means we need to
    3612             :  * hack all leaf frame classes to handle this.
    3613             :  *
    3614             :  * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
    3615             :  * here...  I could switch it all to nscolor, but why bother?
    3616             :  */
    3617             : class nsDisplayReflowCount : public nsDisplayItem {
    3618             : public:
    3619             :   nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3620             :                        const char* aFrameName,
    3621             :                        uint32_t aColor = 0)
    3622           0 :     : nsDisplayItem(aBuilder, aFrame),
    3623           0 :       mFrameName(aFrameName),
    3624           0 :       mColor(aColor)
    3625             :   {
    3626             :     MOZ_COUNT_CTOR(nsDisplayReflowCount);
    3627           0 :   }
    3628           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    3629           0 :   virtual ~nsDisplayReflowCount() {
    3630             :     MOZ_COUNT_DTOR(nsDisplayReflowCount);
    3631           0 :   }
    3632           0 : #endif
    3633           0 : 
    3634             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override {
    3635             :     mFrame->PresShell()->PaintCount(mFrameName, aCtx,
    3636             :                                     mFrame->PresContext(),
    3637             :                                     mFrame, ToReferenceFrame(),
    3638             :                                     mColor);
    3639             :   }
    3640             :   NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
    3641             : protected:
    3642             :   const char* mFrameName;
    3643             :   nscolor mColor;
    3644             : };
    3645             : 
    3646             : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                     \
    3647             :   PR_BEGIN_MACRO                                                              \
    3648             :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    3649             :         PresShell()->IsPaintingFrameCounts()) {                               \
    3650             :         aLists.Outlines()->AppendToTop(                                    \
    3651             :             MakeDisplayItem<nsDisplayReflowCount>(aBuilder, this, _name));      \
    3652             :     }                                                                         \
    3653             :   PR_END_MACRO
    3654             : 
    3655             : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                       \
    3656             :   PR_BEGIN_MACRO                                                              \
    3657             :     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
    3658             :         PresShell()->IsPaintingFrameCounts()) {                               \
    3659             :         aLists.Outlines()->AppendToTop(                                    \
    3660             :              MakeDisplayItem<nsDisplayReflowCount>(aBuilder, this, _name, _color)); \
    3661             :     }                                                                         \
    3662             :   PR_END_MACRO
    3663             : 
    3664             : /*
    3665             :   Macro to be used for classes that don't actually implement BuildDisplayList
    3666             :  */
    3667             : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)                   \
    3668             :   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,                 \
    3669             :                         const nsRect&           aDirtyRect,               \
    3670             :                         const nsDisplayListSet& aLists) {                 \
    3671             :     DO_GLOBAL_REFLOW_COUNT_DSP(#_class);                                  \
    3672             :     _super::BuildDisplayList(aBuilder, aDirtyRect, aLists);               \
    3673             :   }
    3674             : 
    3675             : #else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    3676             : 
    3677             : #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
    3678             : #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
    3679             : #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
    3680             : 
    3681             : #endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
    3682             : 
    3683             : class nsDisplayCaret : public nsDisplayItem {
    3684             : public:
    3685             :   nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame);
    3686           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    3687             :   virtual ~nsDisplayCaret();
    3688             : #endif
    3689             : 
    3690             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    3691             :                            bool* aSnap) const override;
    3692             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3693             :   NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
    3694             : 
    3695             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3696             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    3697             :                                        const StackingContextHelper& aSc,
    3698             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3699             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3700             : 
    3701             : protected:
    3702             :   RefPtr<nsCaret> mCaret;
    3703             :   nsRect mBounds;
    3704             : };
    3705             : 
    3706             : /**
    3707           0 :  * The standard display item to paint the CSS borders of a frame.
    3708           0 :  */
    3709           0 : class nsDisplayBorder : public nsDisplayItem {
    3710             : public:
    3711             :   nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    3712             : 
    3713             : #ifdef NS_BUILD_REFCNT_LOGGING
    3714             :   virtual ~nsDisplayBorder() {
    3715             :     MOZ_COUNT_DTOR(nsDisplayBorder);
    3716             :   }
    3717             : #endif
    3718             : 
    3719             :   virtual bool IsInvisibleInRect(const nsRect& aRect) const override;
    3720             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    3721             :                            bool* aSnap) const override;
    3722             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3723             :                                    LayerManager* aManager,
    3724             :                                    const ContainerLayerParameters& aParameters) override;
    3725             : 
    3726             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3727             :                                              LayerManager* aManager,
    3728             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3729             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3730           0 :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    3731             :                                        const StackingContextHelper& aSc,
    3732             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3733             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3734             : 
    3735             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3736             : 
    3737             :   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
    3738           0 : 
    3739             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
    3740             : 
    3741           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3742           0 :                                          const nsDisplayItemGeometry* aGeometry,
    3743             :                                          nsRegion* aInvalidRegion) const override;
    3744             : 
    3745             :   virtual nsRegion GetTightBounds(nsDisplayListBuilder* aBuilder,
    3746             :                                   bool* aSnap) const override
    3747             :   {
    3748             :     *aSnap = true;
    3749             :     return CalculateBounds<nsRegion>(*mFrame->StyleBorder());
    3750             :   }
    3751             : 
    3752           0 : protected:
    3753             :   void CreateBorderImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3754           0 :                                           mozilla::wr::IpcResourceUpdateQueue& aResource,
    3755           0 :                                           const StackingContextHelper& aSc,
    3756           0 :                                           mozilla::layers::WebRenderLayerManager* aManager,
    3757           0 :                                           nsDisplayListBuilder* aDisplayListBuilder);
    3758             :   template<typename T>
    3759           0 :   T CalculateBounds(const nsStyleBorder& aStyleBorder) const
    3760           0 :   {
    3761           0 :     nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
    3762           0 :     if (aStyleBorder.IsBorderImageLoaded()) {
    3763             :       borderBounds.Inflate(aStyleBorder.GetImageOutset());
    3764           0 :       return borderBounds;
    3765           0 :     } else {
    3766             :       nsMargin border = aStyleBorder.GetComputedBorder();
    3767           0 :       T result;
    3768           0 :       if (border.top > 0) {
    3769             :         result = nsRect(borderBounds.X(), borderBounds.Y(), borderBounds.Width(), border.top);
    3770           0 :       }
    3771           0 :       if (border.right > 0) {
    3772             :         result.OrWith(nsRect(borderBounds.XMost() - border.right, borderBounds.Y(), border.right, borderBounds.Height()));
    3773             :       }
    3774             :       if (border.bottom > 0) {
    3775           0 :         result.OrWith(nsRect(borderBounds.X(), borderBounds.YMost() - border.bottom, borderBounds.Width(), border.bottom));
    3776           0 :       }
    3777           0 :       if (border.left > 0) {
    3778           0 :         result.OrWith(nsRect(borderBounds.X(), borderBounds.Y(), border.left, borderBounds.Height()));
    3779             :       }
    3780           0 : 
    3781           0 :       nscoord radii[8];
    3782           0 :       if (mFrame->GetBorderRadii(radii)) {
    3783             :         if (border.left > 0 || border.top > 0) {
    3784           0 :           nsSize cornerSize(radii[mozilla::eCornerTopLeftX], radii[mozilla::eCornerTopLeftY]);
    3785           0 :           result.OrWith(nsRect(borderBounds.TopLeft(), cornerSize));
    3786           0 :         }
    3787             :         if (border.top > 0 || border.right > 0) {
    3788           0 :           nsSize cornerSize(radii[mozilla::eCornerTopRightX], radii[mozilla::eCornerTopRightY]);
    3789           0 :           result.OrWith(nsRect(borderBounds.TopRight() - nsPoint(cornerSize.width, 0), cornerSize));
    3790           0 :         }
    3791             :         if (border.right > 0 || border.bottom > 0) {
    3792             :           nsSize cornerSize(radii[mozilla::eCornerBottomRightX], radii[mozilla::eCornerBottomRightY]);
    3793           0 :           result.OrWith(nsRect(borderBounds.BottomRight() - nsPoint(cornerSize.width, cornerSize.height), cornerSize));
    3794             :         }
    3795             :         if (border.bottom > 0 || border.left > 0) {
    3796             :           nsSize cornerSize(radii[mozilla::eCornerBottomLeftX], radii[mozilla::eCornerBottomLeftY]);
    3797             :           result.OrWith(nsRect(borderBounds.BottomLeft() - nsPoint(0, cornerSize.height), cornerSize));
    3798             :         }
    3799             :       }
    3800             :       return result;
    3801             :     }
    3802             :   }
    3803             : 
    3804             :   mozilla::Array<mozilla::gfx::Color, 4> mColors;
    3805             :   mozilla::Array<mozilla::LayerCoord, 4> mWidths;
    3806             :   mozilla::Array<mozilla::LayerSize, 4> mCorners;
    3807             :   mozilla::Array<uint8_t, 4> mBorderStyles;
    3808             :   mozilla::LayerRect mRect;
    3809             : 
    3810             :   mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
    3811             :   mozilla::Maybe<nsCSSBorderImageRenderer> mBorderImageRenderer;
    3812             : 
    3813             :   nsRect mBounds;
    3814             :   bool mBorderIsEmpty;
    3815             : };
    3816             : 
    3817             : /**
    3818             :  * A simple display item that just renders a solid color across the
    3819             :  * specified bounds. For canvas frames (in the CSS sense) we split off the
    3820             :  * drawing of the background color into this class (from nsDisplayBackground
    3821           0 :  * via nsDisplayCanvasBackground). This is done so that we can always draw a
    3822             :  * background color to avoid ugly flashes of white when we can't draw a full
    3823             :  * frame tree (ie when a page is loading). The bounds can differ from the
    3824             :  * frame's bounds -- this is needed when a frame/iframe is loading and there
    3825             :  * is not yet a frame tree to go in the frame/iframe so we use the subdoc
    3826             :  * frame of the parent document as a standin.
    3827           0 :  */
    3828             : class nsDisplaySolidColorBase : public nsDisplayItem {
    3829           0 : public:
    3830             :   nsDisplaySolidColorBase(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nscolor aColor)
    3831             :     : nsDisplayItem(aBuilder, aFrame), mColor(aColor)
    3832           0 :   {}
    3833             : 
    3834             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3835             :   {
    3836             :     return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
    3837           0 :   }
    3838           0 : 
    3839             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3840           0 :                                          const nsDisplayItemGeometry* aGeometry,
    3841             :                                          nsRegion* aInvalidRegion) const override
    3842             :   {
    3843           0 :     const nsDisplaySolidColorGeometry* geometry =
    3844             :       static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
    3845             :     if (mColor != geometry->mColor) {
    3846           0 :       bool dummy;
    3847             :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
    3848             :       return;
    3849           0 :     }
    3850           0 :     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
    3851           0 :   }
    3852           0 : 
    3853             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    3854           0 :                                    bool* aSnap) const override
    3855             :   {
    3856             :     *aSnap = false;
    3857           0 :     nsRegion result;
    3858             :     if (NS_GET_A(mColor) == 255) {
    3859           0 :       result = GetBounds(aBuilder, aSnap);
    3860             :     }
    3861             :     return result;
    3862             :   }
    3863             : 
    3864             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override
    3865             :   {
    3866             :     return mozilla::Some(mColor);
    3867             :   }
    3868             : 
    3869             : protected:
    3870             :   nscolor mColor;
    3871             : };
    3872             : 
    3873             : class nsDisplaySolidColor : public nsDisplaySolidColorBase {
    3874             : public:
    3875             :   nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3876             :                       const nsRect& aBounds, nscolor aColor, bool aCanBeReused = true)
    3877           0 :     : nsDisplaySolidColorBase(aBuilder, aFrame, aColor), mBounds(aBounds)
    3878           0 :     , mCanBeReused(aCanBeReused)
    3879           0 :   {
    3880             :     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
    3881             :     MOZ_COUNT_CTOR(nsDisplaySolidColor);
    3882             :   }
    3883             : #ifdef NS_BUILD_REFCNT_LOGGING
    3884             :   virtual ~nsDisplaySolidColor() {
    3885             :     MOZ_COUNT_DTOR(nsDisplaySolidColor);
    3886             :   }
    3887             : #endif
    3888             : 
    3889             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    3890             :                            bool* aSnap) const override;
    3891             : 
    3892             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    3893             :                                    LayerManager* aManager,
    3894             :                                    const ContainerLayerParameters& aParameters) override;
    3895             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    3896             :                                              LayerManager* aManager,
    3897             :                                              const ContainerLayerParameters& aContainerParameters) override;
    3898             : 
    3899             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3900             : 
    3901             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3902           0 : 
    3903             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3904           0 :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    3905             :                                        const StackingContextHelper& aSc,
    3906           0 :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3907             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3908           0 : 
    3909           0 :   NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
    3910             : 
    3911           0 :   virtual bool CanBeReused() const override { return mCanBeReused; }
    3912             : 
    3913             :   int32_t ZIndex() const override
    3914             :   {
    3915             :     if (mOverrideZIndex) {
    3916             :       return mOverrideZIndex.value();
    3917             :     }
    3918             :     return nsDisplaySolidColorBase::ZIndex();
    3919             :   }
    3920             : 
    3921             :   void SetOverrideZIndex(int32_t aZIndex)
    3922             :   {
    3923             :     mOverrideZIndex = mozilla::Some(aZIndex);
    3924             :   }
    3925             : 
    3926             : private:
    3927             :   nsRect  mBounds;
    3928             :   bool mCanBeReused;
    3929             :   mozilla::Maybe<int32_t> mOverrideZIndex;
    3930             : };
    3931             : 
    3932             : /**
    3933             :  * A display item that renders a solid color over a region. This is not
    3934             :  * exposed through CSS, its only purpose is efficient invalidation of
    3935             :  * the find bar highlighter dimmer.
    3936             :  */
    3937             : class nsDisplaySolidColorRegion : public nsDisplayItem {
    3938             :   typedef mozilla::gfx::Color Color;
    3939             : 
    3940             : public:
    3941             :   nsDisplaySolidColorRegion(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    3942           0 :                             const nsRegion& aRegion, nscolor aColor)
    3943           0 :     : nsDisplayItem(aBuilder, aFrame), mRegion(aRegion), mColor(Color::FromABGR(aColor))
    3944           0 :   {
    3945             :     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColorRegions!");
    3946             :     MOZ_COUNT_CTOR(nsDisplaySolidColorRegion);
    3947           0 :   }
    3948             : #ifdef NS_BUILD_REFCNT_LOGGING
    3949           0 :   virtual ~nsDisplaySolidColorRegion() {
    3950             :     MOZ_COUNT_DTOR(nsDisplaySolidColorRegion);
    3951             :   }
    3952           0 : #endif
    3953             : 
    3954             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    3955             :   {
    3956             :     return new nsDisplaySolidColorRegionGeometry(this, aBuilder, mRegion, mColor);
    3957           0 :   }
    3958           0 : 
    3959           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    3960             :                                          const nsDisplayItemGeometry* aGeometry,
    3961           0 :                                          nsRegion* aInvalidRegion) const override
    3962             :   {
    3963           0 :     const nsDisplaySolidColorRegionGeometry* geometry =
    3964             :       static_cast<const nsDisplaySolidColorRegionGeometry*>(aGeometry);
    3965             :     if (mColor == geometry->mColor) {
    3966             :       aInvalidRegion->Xor(geometry->mRegion, mRegion);
    3967             :     } else {
    3968             :       aInvalidRegion->Or(geometry->mRegion.GetBounds(), mRegion.GetBounds());
    3969             :     }
    3970             :   }
    3971           0 : 
    3972             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    3973             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    3974             :                                        const StackingContextHelper& aSc,
    3975             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    3976             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    3977             : 
    3978             :   NS_DISPLAY_DECL_NAME("SolidColorRegion", TYPE_SOLID_COLOR_REGION)
    3979             : 
    3980             : protected:
    3981             : 
    3982             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    3983             :                            bool* aSnap) const override;
    3984             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    3985             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    3986             : 
    3987             : private:
    3988             :   nsRegion mRegion;
    3989             :   Color mColor;
    3990             : };
    3991             : 
    3992             : /**
    3993             :  * A display item to paint one background-image for a frame. Each background
    3994             :  * image layer gets its own nsDisplayBackgroundImage.
    3995             :  */
    3996             : class nsDisplayBackgroundImage : public nsDisplayImageContainer {
    3997             : public:
    3998             :   typedef mozilla::StyleGeometryBox StyleGeometryBox;
    3999             : 
    4000             :   struct InitData {
    4001             :     nsDisplayListBuilder* builder;
    4002             :     nsIFrame* frame;
    4003             :     mozilla::ComputedStyle* backgroundStyle;
    4004             :     nsCOMPtr<imgIContainer> image;
    4005             :     nsRect backgroundRect;
    4006             :     nsRect fillArea;
    4007             :     nsRect destArea;
    4008             :     uint32_t layer;
    4009             :     bool isRasterImage;
    4010             :     bool shouldFixToViewport;
    4011             :   };
    4012             : 
    4013             :   /**
    4014             :    * aLayer signifies which background layer this item represents.
    4015             :    * aIsThemed should be the value of aFrame->IsThemed.
    4016             :    * aBackgroundStyle should be the result of
    4017             :    * nsCSSRendering::FindBackground, or null if FindBackground returned false.
    4018             :    * aBackgroundRect is relative to aFrame.
    4019             :    */
    4020             :   static InitData GetInitData(nsDisplayListBuilder* aBuilder,
    4021             :                               nsIFrame* aFrame,
    4022             :                               uint32_t aLayer,
    4023             :                               const nsRect& aBackgroundRect,
    4024             :                               mozilla::ComputedStyle* aBackgroundStyle);
    4025             : 
    4026             :   explicit nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder,
    4027             :                                     const InitData& aInitData,
    4028             :                                     nsIFrame* aFrameForBounds = nullptr);
    4029             :   virtual ~nsDisplayBackgroundImage();
    4030             : 
    4031             :   // This will create and append new items for all the layers of the
    4032             :   // background. Returns whether we appended a themed background.
    4033             :   // aAllowWillPaintBorderOptimization should usually be left at true, unless
    4034             :   // aFrame has special border drawing that causes opaque borders to not
    4035             :   // actually be opaque.
    4036             :   static bool AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
    4037             :                                          nsIFrame* aFrame,
    4038             :                                          const nsRect& aBackgroundRect,
    4039             :                                          nsDisplayList* aList,
    4040             :                                          bool aAllowWillPaintBorderOptimization = true,
    4041             :                                          mozilla::ComputedStyle* aComputedStyle = nullptr,
    4042             :                                          const nsRect& aBackgroundOriginRect = nsRect(),
    4043             :                                          nsIFrame* aSecondaryReferenceFrame = nullptr);
    4044             : 
    4045             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4046             :                                    LayerManager* aManager,
    4047             :                                    const ContainerLayerParameters& aParameters) override;
    4048             : 
    4049             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4050             :                                              LayerManager* aManager,
    4051             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4052             : 
    4053             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4054             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4055             :                                        const StackingContextHelper& aSc,
    4056             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4057             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4058             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4059             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4060             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4061             :                                  nsRegion* aVisibleRegion) override;
    4062             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4063             :                                    bool* aSnap) const override;
    4064           0 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
    4065             :   /**
    4066           0 :    * GetBounds() returns the background painting area.
    4067             :    */
    4068             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4069           0 :                            bool* aSnap) const override;
    4070             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4071             :   virtual uint32_t GetPerFrameKey() const override
    4072             :   {
    4073             :     return (mLayer << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
    4074             :   }
    4075             : 
    4076             :   NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
    4077             : 
    4078             :   /**
    4079             :    * Return the background positioning area.
    4080             :    * (GetBounds() returns the background painting area.)
    4081             :    * Can be called only when mBackgroundStyle is non-null.
    4082             :    */
    4083             :   nsRect GetPositioningArea() const;
    4084             : 
    4085             :   /**
    4086             :    * Returns true if existing rendered pixels of this display item may need
    4087           0 :    * to be redrawn if the positioning area size changes but its position does
    4088             :    * not.
    4089           0 :    * If false, only the changed painting area needs to be redrawn when the
    4090             :    * positioning area size changes but its position does not.
    4091             :    */
    4092             :   bool RenderingMightDependOnPositioningAreaSizeChange() const;
    4093             : 
    4094             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4095             :   {
    4096             :     return new nsDisplayBackgroundGeometry(this, aBuilder);
    4097             :   }
    4098             : 
    4099             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4100             :                                          const nsDisplayItemGeometry* aGeometry,
    4101             :                                          nsRegion* aInvalidRegion) const override;
    4102             : 
    4103             :   virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
    4104             :                                        nsDisplayListBuilder* aBuilder) override;
    4105             :   virtual already_AddRefed<imgIContainer> GetImage() override;
    4106             :   virtual nsRect GetDestRect() const override;
    4107             : 
    4108             :   virtual void UpdateDrawResult(mozilla::image::ImgDrawResult aResult) override
    4109             :   {
    4110             :     nsDisplayBackgroundGeometry::UpdateDrawResult(this, aResult);
    4111             :   }
    4112             : 
    4113             :   static nsRegion GetInsideClipRegion(const nsDisplayItem* aItem,
    4114             :                                       StyleGeometryBox aClip,
    4115             :                                       const nsRect& aRect,
    4116             :                                       const nsRect& aBackgroundRect);
    4117             : 
    4118             :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const override
    4119             :   {
    4120             :     return mShouldFixToViewport;
    4121             :   }
    4122             : 
    4123             :   virtual nsIFrame* GetDependentFrame() override
    4124             :   {
    4125             :     return mDependentFrame;
    4126             :   }
    4127             : 
    4128             :   void SetDependentFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4129             :   {
    4130             :     if (!aBuilder->IsRetainingDisplayList()) {
    4131             :       return;
    4132             :     }
    4133             :     mDependentFrame = aFrame;
    4134             :     if (aFrame) {
    4135             :       mDependentFrame->AddDisplayItem(this);
    4136             :     }
    4137             :   }
    4138             : 
    4139             :   virtual void RemoveFrame(nsIFrame* aFrame) override
    4140             :   {
    4141             :     if (aFrame == mDependentFrame) {
    4142             :       mDependentFrame = nullptr;
    4143             :     }
    4144             :     nsDisplayItem::RemoveFrame(aFrame);
    4145             :   }
    4146             : 
    4147             : protected:
    4148             :   typedef class mozilla::layers::ImageContainer ImageContainer;
    4149             :   typedef class mozilla::layers::ImageLayer ImageLayer;
    4150             : 
    4151             :   bool CanBuildWebRenderDisplayItems(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
    4152             :   nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
    4153             :                            nsIFrame* aFrameForBounds = nullptr);
    4154             : 
    4155             :   void PaintInternal(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
    4156             :                      const nsRect& aBounds, nsRect* aClipRect);
    4157             : 
    4158             :   // Determine whether we want to be separated into our own layer, independent
    4159             :   // of whether this item can actually be layerized.
    4160             :   enum ImageLayerization {
    4161             :     WHENEVER_POSSIBLE,
    4162             :     ONLY_FOR_SCALING,
    4163             :     NO_LAYER_NEEDED
    4164             :   };
    4165             :   ImageLayerization ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
    4166             :                                          LayerManager* aManager);
    4167             : 
    4168             :   // Cache the result of nsCSSRendering::FindBackground. Always null if
    4169             :   // mIsThemed is true or if FindBackground returned false.
    4170             :   RefPtr<mozilla::ComputedStyle> mBackgroundStyle;
    4171             :   nsCOMPtr<imgIContainer> mImage;
    4172             :   nsIFrame* mDependentFrame;
    4173             :   nsRect mBackgroundRect; // relative to the reference frame
    4174             :   nsRect mFillRect;
    4175             :   nsRect mDestRect;
    4176             :   /* Bounds of this display item */
    4177             :   nsRect mBounds;
    4178             :   uint32_t mLayer;
    4179             :   bool mIsRasterImage;
    4180             :   /* Whether the image should be treated as fixed to the viewport. */
    4181             :   bool mShouldFixToViewport;
    4182             :   uint32_t mImageFlags;
    4183             : };
    4184             : 
    4185             : enum class TableType : uint8_t {
    4186             :   TABLE,
    4187             :   TABLE_COL,
    4188             :   TABLE_COL_GROUP,
    4189             :   TABLE_ROW,
    4190             :   TABLE_ROW_GROUP,
    4191             :   TABLE_CELL,
    4192             : 
    4193             :   TABLE_TYPE_MAX
    4194             : };
    4195             : 
    4196             : enum class TableTypeBits : uint8_t {
    4197             :   COUNT = 3
    4198             : };
    4199             : 
    4200             : static_assert(
    4201             :   static_cast<uint8_t>(TableType::TABLE_TYPE_MAX) < (1 << (static_cast<uint8_t>(TableTypeBits::COUNT) + 1)),
    4202             :   "TableType cannot fit with TableTypeBits::COUNT");
    4203             : TableType GetTableTypeFromFrame(nsIFrame* aFrame);
    4204             : 
    4205             : /**
    4206             :  * A display item to paint background image for table. For table parts, such
    4207             :  * as row, row group, col, col group, when drawing its background, we'll
    4208             :  * create separate background image display item for its containning cell.
    4209             :  * Those background image display items will reference to same DisplayItemData
    4210             :  * if we keep the mFrame point to cell's ancestor frame. We don't want to this
    4211             :  * happened bacause share same DisplatItemData will cause many bugs. So that
    4212             :  * we let mFrame point to cell frame and store the table type of the ancestor
    4213             :  * frame. And use mFrame and table type as key to generate DisplayItemData to
    4214             :  * avoid sharing DisplayItemData.
    4215             :  *
    4216           0 :  * Also store ancestor frame as mStyleFrame for all rendering informations.
    4217           0 :  */
    4218           0 : class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage {
    4219           0 : public:
    4220             :   nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder, const InitData& aInitData, nsIFrame* aCellFrame);
    4221             :   ~nsDisplayTableBackgroundImage();
    4222             : 
    4223             :   virtual uint32_t GetPerFrameKey() const override {
    4224             :     return (mLayer << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
    4225             :            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    4226             :            nsDisplayItem::GetPerFrameKey();
    4227             :   }
    4228             : 
    4229             :   virtual bool IsInvalid(nsRect& aRect) const override;
    4230             : 
    4231             :   virtual nsIFrame* FrameForInvalidation() const override { return mStyleFrame; }
    4232             : 
    4233             :   virtual bool HasDeletedFrame() const override {
    4234             :     return !mStyleFrame || nsDisplayBackgroundImage::HasDeletedFrame();
    4235             :   }
    4236             : 
    4237           0 :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    4238             :     if (aFrame == mStyleFrame) {
    4239             :       mStyleFrame = nullptr;
    4240             :     }
    4241             :     nsDisplayBackgroundImage::RemoveFrame(aFrame);
    4242             :   }
    4243             : 
    4244             :   NS_DISPLAY_DECL_NAME("TableBackgroundImage", TYPE_TABLE_BACKGROUND_IMAGE)
    4245             : protected:
    4246             :   virtual nsIFrame* StyleFrame() const override { return mStyleFrame; }
    4247             : 
    4248             :   nsIFrame* mStyleFrame;
    4249             :   TableType mTableType;
    4250             : };
    4251             : 
    4252             : /**
    4253             :  * A display item to paint the native theme background for a frame.
    4254             :  */
    4255           0 : class nsDisplayThemedBackground : public nsDisplayItem {
    4256             : public:
    4257           0 :   nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4258           0 :                             const nsRect& aBackgroundRect);
    4259           0 :   virtual ~nsDisplayThemedBackground();
    4260             :   void Init(nsDisplayListBuilder* aBuilder);
    4261             : 
    4262             :   void Destroy(nsDisplayListBuilder* aBuilder) override
    4263             :   {
    4264             :     aBuilder->UnregisterThemeGeometry(this);
    4265             :     nsDisplayItem::Destroy(aBuilder);
    4266             :   }
    4267             : 
    4268             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4269             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4270             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4271           0 :                                    bool* aSnap) const override;
    4272             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
    4273             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4274             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4275             :                                        const StackingContextHelper& aSc,
    4276             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4277             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4278             :   virtual bool MustPaintOnContentSide() const override { return true; }
    4279           0 : 
    4280             :   /**
    4281             :    * GetBounds() returns the background painting area.
    4282             :    */
    4283             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4284             :                            bool* aSnap) const override;
    4285             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4286             :   NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
    4287             : 
    4288             :   /**
    4289             :    * Return the background positioning area.
    4290             :    * (GetBounds() returns the background painting area.)
    4291             :    * Can be called only when mBackgroundStyle is non-null.
    4292             :    */
    4293             :   nsRect GetPositioningArea() const;
    4294           0 : 
    4295             :   /**
    4296           0 :    * Return whether our frame's document does not have the state
    4297             :    * NS_DOCUMENT_STATE_WINDOW_INACTIVE.
    4298             :    */
    4299             :   bool IsWindowActive() const;
    4300             : 
    4301             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4302             :   {
    4303             :     return new nsDisplayThemedBackgroundGeometry(this, aBuilder);
    4304             :   }
    4305             : 
    4306             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4307             :                                          const nsDisplayItemGeometry* aGeometry,
    4308             :                                          nsRegion* aInvalidRegion) const override;
    4309             : 
    4310             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    4311             : protected:
    4312             :   nsRect GetBoundsInternal();
    4313             : 
    4314             :   void PaintInternal(nsDisplayListBuilder* aBuilder, gfxContext* aCtx,
    4315             :                      const nsRect& aBounds, nsRect* aClipRect);
    4316             : 
    4317             :   nsRect mBackgroundRect;
    4318             :   nsRect mBounds;
    4319             :   nsITheme::Transparency mThemeTransparency;
    4320             :   uint8_t mAppearance;
    4321             : };
    4322             : 
    4323             : class nsDisplayTableThemedBackground : public nsDisplayThemedBackground {
    4324             : public:
    4325             :   nsDisplayTableThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4326             :                                  const nsRect& aBackgroundRect,
    4327             :                                  nsIFrame* aAncestorFrame)
    4328             :     : nsDisplayThemedBackground(aBuilder, aFrame, aBackgroundRect)
    4329           0 :     , mAncestorFrame(aAncestorFrame)
    4330           0 :     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
    4331           0 :   {
    4332             :     if (aBuilder->IsRetainingDisplayList()) {
    4333           0 :       mAncestorFrame->AddDisplayItem(this);
    4334             :     }
    4335           0 :   }
    4336           0 :   ~nsDisplayTableThemedBackground() {
    4337           0 :     if (mAncestorFrame) {
    4338             :       mAncestorFrame->RemoveDisplayItem(this);
    4339             :     }
    4340           0 :   }
    4341             : 
    4342           0 :   virtual uint32_t GetPerFrameKey() const override {
    4343           0 :     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    4344             :            nsDisplayItem::GetPerFrameKey();
    4345             :   }
    4346           0 : 
    4347           0 :   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
    4348           0 : 
    4349             :   virtual bool HasDeletedFrame() const override {
    4350           0 :     return !mAncestorFrame || nsDisplayThemedBackground::HasDeletedFrame();
    4351           0 :   }
    4352             : 
    4353           0 :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    4354             :     if (aFrame == mAncestorFrame) {
    4355           0 :       mAncestorFrame = nullptr;
    4356             :     }
    4357             :     nsDisplayThemedBackground::RemoveFrame(aFrame);
    4358             :   }
    4359             : 
    4360             :   NS_DISPLAY_DECL_NAME("TableThemedBackground", TYPE_TABLE_THEMED_BACKGROUND_IMAGE)
    4361             : protected:
    4362             :   virtual nsIFrame* StyleFrame() const override { return mAncestorFrame; }
    4363             :   nsIFrame* mAncestorFrame;
    4364             :   TableType mTableType;
    4365             : };
    4366             : 
    4367             : class nsDisplayBackgroundColor : public nsDisplayItem
    4368             : {
    4369             :   typedef mozilla::gfx::Color Color;
    4370             : 
    4371             : public:
    4372             :   nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4373             :                            const nsRect& aBackgroundRect,
    4374             :                            mozilla::ComputedStyle* aBackgroundStyle,
    4375             :                            nscolor aColor)
    4376             :     : nsDisplayItem(aBuilder, aFrame)
    4377           0 :     , mBackgroundRect(aBackgroundRect)
    4378           0 :     , mBackgroundStyle(aBackgroundStyle)
    4379           0 :     , mDependentFrame(nullptr)
    4380           0 :     , mColor(Color::FromABGR(aColor))
    4381             :   {
    4382           0 :     mState.mColor = mColor;
    4383             :   }
    4384           0 :   virtual ~nsDisplayBackgroundColor()
    4385             :   {
    4386           0 :     if (mDependentFrame) {
    4387           0 :       mDependentFrame->RemoveDisplayItem(this);
    4388           0 :     }
    4389             :   }
    4390             : 
    4391             :   virtual void RestoreState() override
    4392             :   {
    4393             :     nsDisplayItem::RestoreState();
    4394             :     mColor = mState.mColor;
    4395             :   }
    4396             : 
    4397             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4398             :                                    LayerManager* aManager,
    4399             :                                    const ContainerLayerParameters& aParameters) override;
    4400             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4401             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4402             :                                              LayerManager* aManager,
    4403             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4404             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4405             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4406             :                                        const StackingContextHelper& aSc,
    4407             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4408             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4409             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4410             :                                    bool* aSnap) const override;
    4411             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
    4412             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4413           0 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4414             : 
    4415             :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    4416           0 :                             float aOpacity,
    4417           0 :                             const DisplayItemClipChain* aClip) override;
    4418             :   virtual bool CanApplyOpacity() const override;
    4419             : 
    4420           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4421             :                            bool* aSnap) const override
    4422           0 :   {
    4423             :     *aSnap = true;
    4424             :     return mBackgroundRect;
    4425           0 :   }
    4426             : 
    4427             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4428             :   {
    4429           0 :     return new nsDisplaySolidColorGeometry(this, aBuilder, mColor.ToABGR());
    4430           0 :   }
    4431             : 
    4432           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4433             :                                          const nsDisplayItemGeometry* aGeometry,
    4434             :                                          nsRegion* aInvalidRegion) const override
    4435           0 :   {
    4436             :     const nsDisplaySolidColorGeometry* geometry = static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
    4437             :     if (mColor.ToABGR() != geometry->mColor) {
    4438           0 :       bool dummy;
    4439             :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
    4440           0 :       return;
    4441             :     }
    4442             :     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
    4443             :   }
    4444             : 
    4445             :   virtual nsIFrame* GetDependentFrame() override
    4446             :   {
    4447             :     return mDependentFrame;
    4448             :   }
    4449             : 
    4450             :   void SetDependentFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4451             :   {
    4452             :     if (!aBuilder->IsRetainingDisplayList()) {
    4453             :       return;
    4454           0 :     }
    4455             :     mDependentFrame = aFrame;
    4456           0 :     if (aFrame) {
    4457           0 :       mDependentFrame->AddDisplayItem(this);
    4458             :     }
    4459           0 :   }
    4460           0 : 
    4461             :   virtual void RemoveFrame(nsIFrame* aFrame) override
    4462           0 :   {
    4463             :     if (aFrame == mDependentFrame) {
    4464             :       mDependentFrame = nullptr;
    4465             :     }
    4466             :     nsDisplayItem::RemoveFrame(aFrame);
    4467             :   }
    4468             : 
    4469             :   NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
    4470             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    4471             : 
    4472             : protected:
    4473             :   const nsRect mBackgroundRect;
    4474             :   RefPtr<mozilla::ComputedStyle> mBackgroundStyle;
    4475             :   nsIFrame* mDependentFrame;
    4476             :   mozilla::gfx::Color mColor;
    4477             : 
    4478             :   struct {
    4479             :     mozilla::gfx::Color mColor;
    4480             :   } mState;
    4481             : };
    4482             : 
    4483             : class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor
    4484             : {
    4485             : public:
    4486             :   nsDisplayTableBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4487             :                                 const nsRect& aBackgroundRect,
    4488             :                                 mozilla::ComputedStyle* aBackgroundStyle,
    4489             :                                 nscolor aColor,
    4490             :                                 nsIFrame* aAncestorFrame)
    4491             :     : nsDisplayBackgroundColor(aBuilder, aFrame, aBackgroundRect, aBackgroundStyle, aColor)
    4492           0 :     , mAncestorFrame(aAncestorFrame)
    4493           0 :     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
    4494           0 :   {
    4495             :     if (aBuilder->IsRetainingDisplayList()) {
    4496           0 :       mAncestorFrame->AddDisplayItem(this);
    4497             :     }
    4498           0 :   }
    4499             :   ~nsDisplayTableBackgroundColor() {
    4500           0 :     if (mAncestorFrame) {
    4501           0 :       mAncestorFrame->RemoveDisplayItem(this);
    4502             :     }
    4503             :   }
    4504           0 : 
    4505           0 :   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
    4506           0 : 
    4507             :   virtual bool HasDeletedFrame() const override {
    4508           0 :     return !mAncestorFrame || nsDisplayBackgroundColor::HasDeletedFrame();
    4509           0 :   }
    4510             : 
    4511           0 :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    4512           0 :     if (aFrame == mAncestorFrame) {
    4513           0 :       mAncestorFrame = nullptr;
    4514             :     }
    4515             :     nsDisplayBackgroundColor::RemoveFrame(aFrame);
    4516           0 :   }
    4517             : 
    4518             :   virtual uint32_t GetPerFrameKey() const override {
    4519             :     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    4520             :            nsDisplayItem::GetPerFrameKey();
    4521             :   }
    4522             : 
    4523             :   NS_DISPLAY_DECL_NAME("TableBackgroundColor", TYPE_TABLE_BACKGROUND_COLOR)
    4524             : protected:
    4525             :   nsIFrame* mAncestorFrame;
    4526             :   TableType mTableType;
    4527             : };
    4528             : 
    4529           0 : class nsDisplayClearBackground : public nsDisplayItem
    4530             : {
    4531             : public:
    4532           0 :   nsDisplayClearBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4533           0 :     : nsDisplayItem(aBuilder, aFrame)
    4534             :   { }
    4535             : 
    4536           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4537             :                            bool* aSnap) const override
    4538           0 :   {
    4539           0 :     *aSnap = true;
    4540             :     return nsRect(ToReferenceFrame(), Frame()->GetSize());
    4541             :   }
    4542             : 
    4543             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4544             :                                    bool* aSnap) const override {
    4545             :     *aSnap = false;
    4546             :     return GetBounds(aBuilder, aSnap);
    4547             :   }
    4548             : 
    4549             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override
    4550             :   {
    4551             :     return mozilla::Some(NS_RGBA(0, 0, 0, 0));
    4552             :   }
    4553             : 
    4554             :   virtual bool ClearsBackground() const override
    4555             :   {
    4556             :     return true;
    4557             :   }
    4558             : 
    4559             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    4560             :                                    LayerManager* aManager,
    4561             :                                    const ContainerLayerParameters& aParameters) override
    4562             :   {
    4563             :     return mozilla::LAYER_ACTIVE_FORCE;
    4564             :   }
    4565             : 
    4566             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    4567             :                                              LayerManager* aManager,
    4568             :                                              const ContainerLayerParameters& aContainerParameters) override;
    4569           0 : 
    4570             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4571             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    4572             :                                const StackingContextHelper& aSc,
    4573             :                                mozilla::layers::WebRenderLayerManager* aManager,
    4574             :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    4575             : 
    4576             :   NS_DISPLAY_DECL_NAME("ClearBackground", TYPE_CLEAR_BACKGROUND)
    4577             : };
    4578             : 
    4579             : /**
    4580             :  * The standard display item to paint the outer CSS box-shadows of a frame.
    4581             :  */
    4582             : class nsDisplayBoxShadowOuter final : public nsDisplayItem {
    4583             : public:
    4584             :   nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4585           0 :     : nsDisplayItem(aBuilder, aFrame)
    4586           0 :     , mOpacity(1.0f)
    4587           0 :   {
    4588             :     MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
    4589             :     mBounds = GetBoundsInternal();
    4590             :   }
    4591             : #ifdef NS_BUILD_REFCNT_LOGGING
    4592             :   virtual ~nsDisplayBoxShadowOuter() {
    4593             :     MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
    4594             :   }
    4595             : #endif
    4596           0 : 
    4597             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4598             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4599             :                            bool* aSnap) const override;
    4600             :   virtual bool IsInvisibleInRect(const nsRect& aRect) const override;
    4601             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4602           0 :                                  nsRegion* aVisibleRegion) override;
    4603             :   NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
    4604             : 
    4605             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4606           0 :                                          const nsDisplayItemGeometry* aGeometry,
    4607           0 :                                          nsRegion* aInvalidRegion) const override;
    4608           0 : 
    4609           0 :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    4610           0 :                             float aOpacity,
    4611             :                             const DisplayItemClipChain* aClip) override
    4612           0 :   {
    4613             :     NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
    4614             :     mOpacity = aOpacity;
    4615           0 :     IntersectClip(aBuilder, aClip, false);
    4616             :   }
    4617           0 :   virtual bool CanApplyOpacity() const override
    4618           0 :   {
    4619           0 :     return true;
    4620           0 :   }
    4621             : 
    4622           0 :   virtual void RestoreState() override
    4623             :   {
    4624           0 :     nsDisplayItem::RestoreState();
    4625             :     mVisibleRegion.SetEmpty();
    4626             :     mOpacity = 1.0f;
    4627             :   }
    4628             : 
    4629             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4630             :   {
    4631             :     return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
    4632             :   }
    4633             : 
    4634             :   bool CanBuildWebRenderDisplayItems();
    4635             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4636             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4637             :                                        const StackingContextHelper& aSc,
    4638             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4639             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4640             :   nsRect GetBoundsInternal();
    4641             : 
    4642             : private:
    4643             :   nsRegion mVisibleRegion;
    4644             :   nsRect mBounds;
    4645             :   float mOpacity;
    4646             : };
    4647             : 
    4648             : /**
    4649             :  * The standard display item to paint the inner CSS box-shadows of a frame.
    4650             :  */
    4651           0 : class nsDisplayBoxShadowInner : public nsDisplayItem {
    4652           0 : public:
    4653           0 :   nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4654             :     : nsDisplayItem(aBuilder, aFrame) {
    4655             :     MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
    4656           0 :   }
    4657             : #ifdef NS_BUILD_REFCNT_LOGGING
    4658           0 :   virtual ~nsDisplayBoxShadowInner() {
    4659           0 :     MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
    4660           0 :   }
    4661             : #endif
    4662             : 
    4663             :   virtual void RestoreState() override
    4664             :   {
    4665           0 :     nsDisplayItem::RestoreState();
    4666             :     mVisibleRegion.SetEmpty();
    4667           0 :   }
    4668             : 
    4669           0 :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4670             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4671             :                                  nsRegion* aVisibleRegion) override;
    4672           0 :   NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
    4673             : 
    4674             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    4675             :   {
    4676           0 :     return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
    4677           0 :   }
    4678             : 
    4679             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    4680             :                                          const nsDisplayItemGeometry* aGeometry,
    4681           0 :                                          nsRegion* aInvalidRegion) const override
    4682             :   {
    4683           0 :     const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
    4684             :     if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
    4685             :       // nsDisplayBoxShadowInner is based around the padding rect, but it can
    4686             :       // touch pixels outside of this. We should invalidate the entire bounds.
    4687             :       bool snap;
    4688             :       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
    4689             :     }
    4690             :   }
    4691             : 
    4692             :   static bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
    4693             :                                          nsIFrame* aFrame,
    4694             :                                          nsPoint aReferencePoint);
    4695             :   static void CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4696             :                                                     const StackingContextHelper& aSc,
    4697             :                                                     nsRegion& aVisibleRegion,
    4698             :                                                     nsIFrame* aFrame,
    4699             :                                                     const nsRect aBorderRect);
    4700             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4701             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4702             :                                        const StackingContextHelper& aSc,
    4703             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4704             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4705             : 
    4706             : private:
    4707             :   nsRegion mVisibleRegion;
    4708             : };
    4709             : 
    4710             : /**
    4711             :  * The standard display item to paint the CSS outline of a frame.
    4712             :  */
    4713           0 : class nsDisplayOutline : public nsDisplayItem {
    4714           0 : public:
    4715           0 :   nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
    4716             :     nsDisplayItem(aBuilder, aFrame) {
    4717             :     MOZ_COUNT_CTOR(nsDisplayOutline);
    4718             :   }
    4719             : #ifdef NS_BUILD_REFCNT_LOGGING
    4720             :   virtual ~nsDisplayOutline() {
    4721             :     MOZ_COUNT_DTOR(nsDisplayOutline);
    4722             :   }
    4723             : #endif
    4724             : 
    4725             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4726           0 :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    4727             :                                        const StackingContextHelper& aSc,
    4728             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    4729             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    4730             :   virtual bool IsInvisibleInRect(const nsRect& aRect) const override;
    4731             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
    4732             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4733             :   NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
    4734             : };
    4735             : 
    4736             : /**
    4737             :  * A class that lets you receive events within the frame bounds but never paints.
    4738             :  */
    4739           0 : class nsDisplayEventReceiver : public nsDisplayItem {
    4740           0 : public:
    4741           0 :   nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4742             :     : nsDisplayItem(aBuilder, aFrame) {
    4743             :     MOZ_COUNT_CTOR(nsDisplayEventReceiver);
    4744             :   }
    4745             : #ifdef NS_BUILD_REFCNT_LOGGING
    4746             :   virtual ~nsDisplayEventReceiver() {
    4747             :     MOZ_COUNT_DTOR(nsDisplayEventReceiver);
    4748             :   }
    4749             : #endif
    4750             : 
    4751             :   void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4752           0 :                HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4753             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4754             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    4755             :                                const StackingContextHelper& aSc,
    4756             :                                mozilla::layers::WebRenderLayerManager* aManager,
    4757             :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    4758             : 
    4759             :   NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
    4760             : };
    4761             : 
    4762             : /**
    4763             :  * Similar to nsDisplayEventReceiver in that it is used for hit-testing. However
    4764             :  * this gets built when we're doing widget painting and we need to send the
    4765             :  * compositor some hit-test info for a frame. This is effectively a dummy item
    4766             :  * whose sole purpose is to carry the hit-test info to the compositor.
    4767             :  */
    4768             : class nsDisplayCompositorHitTestInfo : public nsDisplayEventReceiver {
    4769           0 : public:
    4770           0 :   nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4771           0 :                                  mozilla::gfx::CompositorHitTestInfo aHitTestInfo,
    4772           0 :                                  uint32_t aIndex = 0,
    4773             :                                  const mozilla::Maybe<nsRect>& aArea = mozilla::Nothing());
    4774             : 
    4775             : #ifdef NS_BUILD_REFCNT_LOGGING
    4776             :   virtual ~nsDisplayCompositorHitTestInfo()
    4777             :   {
    4778             :     MOZ_COUNT_DTOR(nsDisplayCompositorHitTestInfo);
    4779             :   }
    4780             : #endif
    4781             : 
    4782             :   mozilla::gfx::CompositorHitTestInfo HitTestInfo() const { return mHitTestInfo; }
    4783             : 
    4784             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    4785             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    4786             :                                const StackingContextHelper& aSc,
    4787             :                                mozilla::layers::WebRenderLayerManager* aManager,
    4788             :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    4789             :   void WriteDebugInfo(std::stringstream& aStream) override;
    4790             :   uint32_t GetPerFrameKey() const override;
    4791             :   int32_t ZIndex() const override;
    4792             :   void SetOverrideZIndex(int32_t aZIndex);
    4793             : 
    4794             :   /**
    4795           0 :    * Returns the hit test area of this item.
    4796           0 :    */
    4797             :   const nsRect& Area() const { return mArea; }
    4798             : 
    4799             :   /**
    4800             :    * ApplyOpacity() is overriden for opacity flattening.
    4801           0 :    */
    4802             :   void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
    4803           0 :                     const DisplayItemClipChain* aClip) override {}
    4804             : 
    4805           0 :   /**
    4806           0 :    * CanApplyOpacity() is overriden for opacity flattening.
    4807             :    */
    4808             :   bool CanApplyOpacity() const override { return true; }
    4809           0 : 
    4810             :   nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override
    4811             :   {
    4812             :     *aSnap = false;
    4813             :     return nsRect();
    4814             :   }
    4815             : 
    4816             :   NS_DISPLAY_DECL_NAME("CompositorHitTestInfo", TYPE_COMPOSITOR_HITTEST_INFO)
    4817             : 
    4818             : private:
    4819             :   mozilla::gfx::CompositorHitTestInfo mHitTestInfo;
    4820             :   mozilla::Maybe<mozilla::layers::FrameMetrics::ViewID> mScrollTarget;
    4821             :   nsRect mArea;
    4822             :   uint32_t mIndex;
    4823             :   mozilla::Maybe<int32_t> mOverrideZIndex;
    4824             :   int32_t mAppUnitsPerDevPixel;
    4825             : };
    4826             : 
    4827             : /**
    4828             :  * A class that lets you wrap a display list as a display item.
    4829             :  *
    4830             :  * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
    4831             :  * list has many items, it's not clear which one has the 'underlying frame'.
    4832             :  * Thus we force the creator to specify what the underlying frame is. The
    4833             :  * underlying frame should be the root of a stacking context, because sorting
    4834             :  * a list containing this item will not get at the children.
    4835             :  *
    4836             :  * In some cases (e.g., clipping) we want to wrap a list but we don't have a
    4837             :  * particular underlying frame that is a stacking context root. In that case
    4838             :  * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must
    4839             :  * detect and handle this case.
    4840             :  */
    4841             : class nsDisplayWrapList : public nsDisplayItem {
    4842             : public:
    4843             :   /**
    4844             :    * Takes all the items from aList and puts them in our list.
    4845             :    */
    4846             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4847             :                     nsDisplayList* aList, bool aAnonymous = false);
    4848             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4849             :                     nsDisplayList* aList,
    4850             :                     const ActiveScrolledRoot* aActiveScrolledRoot,
    4851             :                     bool aClearClipChain = false,
    4852             :                     uint32_t aIndex = 0,
    4853             :                     bool aAnonymous = false);
    4854             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    4855             :                     nsDisplayItem* aItem, bool aAnonymous = false);
    4856             :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    4857             :     : nsDisplayItem(aBuilder, aFrame)
    4858             :     , mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot())
    4859             :     , mOverrideZIndex(0)
    4860             :     , mIndex(0)
    4861             :     , mHasZIndexOverride(false)
    4862             :   {
    4863             :     MOZ_COUNT_CTOR(nsDisplayWrapList);
    4864             :     mBaseBuildingRect = GetBuildingRect();
    4865             :     mListPtr = &mList;
    4866           0 :   }
    4867           0 : 
    4868             :   /**
    4869             :    * A custom copy-constructor that does not copy mList, as this would mutate
    4870             :    * the other item.
    4871             :    */
    4872             :   nsDisplayWrapList(const nsDisplayWrapList& aOther) = delete;
    4873           0 :   nsDisplayWrapList(nsDisplayListBuilder* aBuilder, const nsDisplayWrapList& aOther)
    4874           0 :     : nsDisplayItem(aBuilder, aOther)
    4875           0 :     , mListPtr(&mList)
    4876           0 :     , mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot)
    4877             :     , mMergedFrames(aOther.mMergedFrames)
    4878           0 :     , mBounds(aOther.mBounds)
    4879           0 :     , mBaseBuildingRect(aOther.mBaseBuildingRect)
    4880             :     , mOverrideZIndex(aOther.mOverrideZIndex)
    4881             :     , mIndex(aOther.mIndex)
    4882             :     , mHasZIndexOverride(aOther.mHasZIndexOverride)
    4883           0 :     , mClearingClipChain(aOther.mClearingClipChain)
    4884             :   {
    4885           0 :     MOZ_COUNT_CTOR(nsDisplayWrapList);
    4886             :   }
    4887           0 : 
    4888             :   virtual ~nsDisplayWrapList();
    4889           0 : 
    4890             :   virtual const nsDisplayWrapList* AsDisplayWrapList() const override
    4891             :   {
    4892           0 :     return this;
    4893           0 :   }
    4894           0 :   virtual nsDisplayWrapList* AsDisplayWrapList() override
    4895           0 :   {
    4896             :     return this;
    4897             :   }
    4898             : 
    4899             :   virtual void Destroy(nsDisplayListBuilder* aBuilder) override {
    4900             :     mList.DeleteAll(aBuilder);
    4901             :     nsDisplayItem::Destroy(aBuilder);
    4902             :   }
    4903             : 
    4904             :   /**
    4905             :    * Creates a new nsDisplayWrapList that holds a pointer to the display list
    4906             :    * owned by the given nsDisplayItem. The new nsDisplayWrapList will be added
    4907             :    * to the bottom of this item's contents.
    4908           0 :    */
    4909             :   virtual void MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
    4910             :                                         const nsDisplayItem* aItem) override;
    4911             : 
    4912           0 :   /**
    4913           0 :    * Call this if the wrapped list is changed.
    4914           0 :    */
    4915           0 :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
    4916             :   {
    4917           0 :     // Clear the clip chain up to the asr, but don't store it, so that we'll recover
    4918             :     // it when we reuse the item.
    4919             :     if (mClearingClipChain) {
    4920           0 :       const DisplayItemClipChain* clip = mState.mClipChain;
    4921           0 :       while (clip && ActiveScrolledRoot::IsAncestor(GetActiveScrolledRoot(), clip->mASR)) {
    4922           0 :         clip = clip->mParent;
    4923             :       }
    4924             :       SetClipChain(clip, false);
    4925             :     }
    4926             : 
    4927             :     nsRect buildingRect;
    4928             :     mBounds =
    4929             :       mListPtr->GetClippedBoundsWithRespectToASR(aBuilder, mActiveScrolledRoot, &buildingRect);
    4930           0 :     // The display list may contain content that's visible outside the visible
    4931           0 :     // rect (i.e. the current dirty rect) passed in when the item was created.
    4932           0 :     // This happens when the dirty rect has been restricted to the visual
    4933             :     // overflow rect of a frame for some reason (e.g. when setting up dirty
    4934             :     // rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
    4935             :     // frame contains placeholders for out-of-flows that aren't descendants of
    4936             :     // the frame.
    4937             :     buildingRect.UnionRect(mBaseBuildingRect, buildingRect);
    4938             :     SetBuildingRect(buildingRect);
    4939             :   }
    4940             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    4941             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    4942             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    4943             :                            bool* aSnap) const override;
    4944           0 :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    4945             :                                    bool* aSnap) const override;
    4946           0 :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
    4947             :   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
    4948             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    4949           0 :                                  nsRegion* aVisibleRegion) override;
    4950             : 
    4951           0 :   virtual uint32_t GetPerFrameKey() const override
    4952             :   {
    4953             :     return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
    4954           0 :   }
    4955             : 
    4956           0 :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    4957           0 :   {
    4958           0 :     return false;
    4959             :   }
    4960           0 : 
    4961             :   virtual void Merge(const nsDisplayItem* aItem) override
    4962           0 :   {
    4963           0 :     MOZ_ASSERT(CanMerge(aItem));
    4964             :     MergeFromTrackingMergedFrames(static_cast<const nsDisplayWrapList*>(aItem));
    4965           0 :   }
    4966             : 
    4967           0 :   virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) const override
    4968             :   {
    4969             :     aFrames->AppendElements(mMergedFrames);
    4970           0 :   }
    4971             : 
    4972           0 :   virtual bool HasMergedFrames() const override
    4973             :   {
    4974             :     return !mMergedFrames.IsEmpty();
    4975           0 :   }
    4976             : 
    4977           0 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    4978             :   {
    4979             :     return true;
    4980           0 :   }
    4981           0 : 
    4982           0 :   virtual bool IsInvalid(nsRect& aRect) const override
    4983           0 :   {
    4984           0 :     if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
    4985             :       return true;
    4986           0 :     }
    4987             :     nsRect temp;
    4988           0 :     for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
    4989           0 :       if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
    4990             :         aRect.SetEmpty();
    4991           0 :         return true;
    4992             :       }
    4993             :       aRect = aRect.Union(temp);
    4994             :     }
    4995           0 :     aRect += ToReferenceFrame();
    4996             :     return !aRect.IsEmpty();
    4997           0 :   }
    4998             :   NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
    4999             : 
    5000             :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override;
    5001           0 : 
    5002             :   virtual nsDisplayList* GetSameCoordinateSystemChildren() const override
    5003             :   {
    5004           0 :     NS_ASSERTION(mListPtr->IsEmpty() || !ReferenceFrame() ||
    5005             :                  !mListPtr->GetBottom()->ReferenceFrame() ||
    5006           0 :                  mListPtr->GetBottom()->ReferenceFrame() == ReferenceFrame(),
    5007             :                  "Children must have same reference frame");
    5008           0 :     return mListPtr;
    5009             :   }
    5010             : 
    5011             :   virtual RetainedDisplayList* GetChildren() const override { return mListPtr; }
    5012             : 
    5013             :   virtual int32_t ZIndex() const override
    5014             :   {
    5015             :     return (mHasZIndexOverride) ? mOverrideZIndex : nsDisplayItem::ZIndex();
    5016             :   }
    5017             : 
    5018             :   void SetOverrideZIndex(int32_t aZIndex)
    5019             :   {
    5020             :     mHasZIndexOverride = true;
    5021             :     mOverrideZIndex = aZIndex;
    5022             :   }
    5023             : 
    5024             :   void SetReferenceFrame(const nsIFrame* aFrame);
    5025           0 : 
    5026             :   /**
    5027           0 :    * This creates a copy of this item, but wrapping aItem instead of
    5028           0 :    * our existing list. Only gets called if this item returned nullptr
    5029             :    * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
    5030             :    * GetUnderlyingFrame().
    5031             :    */
    5032             :   virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
    5033             :                                            nsDisplayItem* aItem) {
    5034             :     NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!");
    5035             :     return nullptr;
    5036             :   }
    5037             : 
    5038             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5039             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    5040             :                                        const StackingContextHelper& aSc,
    5041             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    5042           0 :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    5043             : 
    5044           0 :   const ActiveScrolledRoot* GetFrameActiveScrolledRoot() { return mFrameActiveScrolledRoot; }
    5045           0 : 
    5046           0 : protected:
    5047           0 :   nsDisplayWrapList() = delete;
    5048           0 : 
    5049           0 :   void MergeFromTrackingMergedFrames(const nsDisplayWrapList* aOther)
    5050           0 :   {
    5051             :     mBounds.UnionRect(mBounds, aOther->mBounds);
    5052             :     nsRect buildingRect;
    5053             :     buildingRect.UnionRect(GetBuildingRect(), aOther->GetBuildingRect());
    5054             :     SetBuildingRect(buildingRect);
    5055             :     mMergedFrames.AppendElement(aOther->mFrame);
    5056             :     mMergedFrames.AppendElements(aOther->mMergedFrames);
    5057             :   }
    5058             : 
    5059             :   RetainedDisplayList mList;
    5060             :   RetainedDisplayList* mListPtr;
    5061             :   // The active scrolled root for the frame that created this
    5062             :   // wrap list.
    5063             :   RefPtr<const ActiveScrolledRoot> mFrameActiveScrolledRoot;
    5064             :   // The frames from items that have been merged into this item, excluding
    5065             :   // this item's own frame.
    5066             :   nsTArray<nsIFrame*> mMergedFrames;
    5067             :   nsRect mBounds;
    5068             :   // Displaylist building rect contributed by this display item itself.
    5069             :   // Our mBuildingRect may include the visible areas of children.
    5070             :   nsRect mBaseBuildingRect;
    5071             :   int32_t mOverrideZIndex;
    5072             :   uint32_t mIndex;
    5073             :   bool mHasZIndexOverride;
    5074             :   bool mClearingClipChain = false;
    5075             : };
    5076             : 
    5077             : /**
    5078             :  * We call WrapDisplayList on the in-flow lists: BorderBackground(),
    5079             :  * BlockBorderBackgrounds() and Content().
    5080             :  * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
    5081             :  * and Floats(). This is done to support special wrapping processing for frames
    5082             :  * that may not be in-flow descendants of the current frame.
    5083             :  */
    5084             : class nsDisplayWrapper {
    5085             : public:
    5086             :   // This is never instantiated directly (it has pure virtual methods), so no
    5087             :   // need to count constructors and destructors.
    5088             : 
    5089             :   virtual bool WrapBorderBackground() { return true; }
    5090             :   virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
    5091             :                                   nsIFrame* aFrame, nsDisplayList* aList) = 0;
    5092             :   virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
    5093             :                                   nsDisplayItem* aItem) = 0;
    5094             : 
    5095             :   nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5096             :                      const nsDisplayListSet& aIn, const nsDisplayListSet& aOut);
    5097             :   nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5098             :                             const nsDisplayListSet& aLists);
    5099             : protected:
    5100             :   nsDisplayWrapper() = default;
    5101             : };
    5102             : 
    5103             : /**
    5104             :  * The standard display item to paint a stacking context with translucency
    5105             :  * set by the stacking context root frame's 'opacity' style.
    5106             :  */
    5107             : class nsDisplayOpacity : public nsDisplayWrapList {
    5108             : public:
    5109             :   nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5110             :                    nsDisplayList* aList,
    5111             :                    const ActiveScrolledRoot* aActiveScrolledRoot,
    5112             :                    bool aForEventsAndPluginsOnly);
    5113             : 
    5114             :   nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
    5115             :                    const nsDisplayOpacity& aOther)
    5116             :     : nsDisplayWrapList(aBuilder, aOther)
    5117             :     , mOpacity(aOther.mOpacity)
    5118             :     , mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
    5119             :     , mOpacityAppliedToChildren(false)
    5120             :   {
    5121             :     // We should not try to merge flattened opacities.
    5122             :     MOZ_ASSERT(!aOther.mOpacityAppliedToChildren);
    5123             :   }
    5124             : 
    5125             : #ifdef NS_BUILD_REFCNT_LOGGING
    5126             :   virtual ~nsDisplayOpacity();
    5127             : #endif
    5128             : 
    5129             :   virtual void RestoreState() override
    5130             :   {
    5131             :     nsDisplayItem::RestoreState();
    5132             :     mOpacity = mState.mOpacity;
    5133             :     mOpacityAppliedToChildren = false;
    5134             :   }
    5135             : 
    5136             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5137             :   {
    5138             :     MOZ_COUNT_CTOR(nsDisplayOpacity);
    5139             :     return MakeDisplayItem<nsDisplayOpacity>(aBuilder, *this);
    5140             :   }
    5141             : 
    5142             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    5143             :                                    bool* aSnap) const override;
    5144             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5145             :                                              LayerManager* aManager,
    5146           0 :                                              const ContainerLayerParameters& aContainerParameters) override;
    5147             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5148             :                                    LayerManager* aManager,
    5149             :                                    const ContainerLayerParameters& aParameters) override;
    5150             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    5151           0 :                                  nsRegion* aVisibleRegion) override;
    5152             : 
    5153             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    5154           0 :   {
    5155             :     // items for the same content element should be merged into a single
    5156           0 :     // compositing group
    5157             :     // aItem->GetUnderlyingFrame() returns non-null because it's nsDisplayOpacity
    5158             :     return HasSameTypeAndClip(aItem) && HasSameContent(aItem);
    5159             :   }
    5160             : 
    5161             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    5162             :   {
    5163           0 :     return new nsDisplayOpacityGeometry(this, aBuilder, mOpacity);
    5164             :   }
    5165           0 : 
    5166             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    5167             :                                          const nsDisplayItemGeometry* aGeometry,
    5168           0 :                                          nsRegion* aInvalidRegion) const override;
    5169             : 
    5170             :   virtual bool IsInvalid(nsRect& aRect) const override
    5171             :   {
    5172             :     if (mForEventsAndPluginsOnly) {
    5173             :       return false;
    5174             :     }
    5175             :     return nsDisplayWrapList::IsInvalid(aRect);
    5176             :   }
    5177             :   virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
    5178             :                             float aOpacity,
    5179             :                             const DisplayItemClipChain* aClip) override;
    5180             :   virtual bool CanApplyOpacity() const override;
    5181             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
    5182             : 
    5183           0 :   /**
    5184             :    * Returns true if ShouldFlattenAway() applied opacity to children.
    5185             :    */
    5186             :   bool OpacityAppliedToChildren() const { return mOpacityAppliedToChildren; }
    5187             : 
    5188             :   static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
    5189             :   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
    5190             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    5191             : 
    5192             :   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
    5193             : 
    5194             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5195             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    5196             :                                        const StackingContextHelper& aSc,
    5197             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    5198             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    5199             : 
    5200             :   float GetOpacity() { return mOpacity; }
    5201             : 
    5202             : private:
    5203             :   bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
    5204             : 
    5205             :   float mOpacity;
    5206             :   bool mForEventsAndPluginsOnly;
    5207             :   bool mOpacityAppliedToChildren;
    5208             : 
    5209             :   struct {
    5210             :     float mOpacity;
    5211             :   } mState;
    5212             : };
    5213             : 
    5214           0 : class nsDisplayBlendMode : public nsDisplayWrapList {
    5215             : public:
    5216           0 :   nsDisplayBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5217           0 :                         nsDisplayList* aList, uint8_t aBlendMode,
    5218           0 :                         const ActiveScrolledRoot* aActiveScrolledRoot,
    5219           0 :                         uint32_t aIndex = 0);
    5220             :   nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
    5221             :                      const nsDisplayBlendMode& aOther)
    5222             :     : nsDisplayWrapList(aBuilder, aOther)
    5223             :     , mBlendMode(aOther.mBlendMode)
    5224           0 :     , mIndex(aOther.mIndex)
    5225             :   {}
    5226           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    5227           0 :   virtual ~nsDisplayBlendMode();
    5228             : #endif
    5229             : 
    5230             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5231             :   {
    5232             :     MOZ_COUNT_CTOR(nsDisplayBlendMode);
    5233             :     return MakeDisplayItem<nsDisplayBlendMode>(aBuilder, *this);
    5234             :   }
    5235             : 
    5236           0 :   nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    5237             :                            bool* aSnap) const override;
    5238             : 
    5239             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5240             :                                              LayerManager* aManager,
    5241           0 :                                              const ContainerLayerParameters& aContainerParameters) override;
    5242           0 :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    5243           0 :                                          const nsDisplayItemGeometry* aGeometry,
    5244             :                                          nsRegion* aInvalidRegion) const override
    5245             :   {
    5246             :     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
    5247             :   }
    5248             :   virtual uint32_t GetPerFrameKey() const override {
    5249             :     return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
    5250             :   }
    5251             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5252             :                                    LayerManager* aManager,
    5253             :                                    const ContainerLayerParameters& aParameters) override;
    5254             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5255             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    5256             :                                const StackingContextHelper& aSc,
    5257             :                                mozilla::layers::WebRenderLayerManager* aManager,
    5258           0 :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    5259             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    5260           0 :                                  nsRegion* aVisibleRegion) override;
    5261             : 
    5262             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override;
    5263             : 
    5264           0 :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    5265             :   {
    5266             :     return false;
    5267             :   }
    5268             :   mozilla::gfx::CompositionOp BlendMode();
    5269             : 
    5270             :   NS_DISPLAY_DECL_NAME("BlendMode", TYPE_BLEND_MODE)
    5271             : 
    5272             : protected:
    5273             :   uint8_t mBlendMode;
    5274             :   uint32_t mIndex;
    5275             : };
    5276             : 
    5277             : class nsDisplayTableBlendMode : public nsDisplayBlendMode
    5278             : {
    5279             : public:
    5280             :   nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5281             :                           nsDisplayList* aList, uint8_t aBlendMode,
    5282             :                           const ActiveScrolledRoot* aActiveScrolledRoot,
    5283             :                           uint32_t aIndex, nsIFrame* aAncestorFrame)
    5284             :     : nsDisplayBlendMode(aBuilder, aFrame, aList, aBlendMode, aActiveScrolledRoot, aIndex)
    5285             :     , mAncestorFrame(aAncestorFrame)
    5286             :     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
    5287           0 :   {
    5288             :     if (aBuilder->IsRetainingDisplayList()) {
    5289           0 :       mAncestorFrame->AddDisplayItem(this);
    5290           0 :     }
    5291           0 :   }
    5292             : 
    5293           0 :   nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder,
    5294           0 :                           const nsDisplayTableBlendMode& aOther)
    5295             :     : nsDisplayBlendMode(aBuilder, aOther)
    5296           0 :     , mAncestorFrame(aOther.mAncestorFrame)
    5297           0 :     , mTableType(aOther.mTableType)
    5298           0 :   {
    5299           0 :     if (aBuilder->IsRetainingDisplayList()) {
    5300             :       mAncestorFrame->AddDisplayItem(this);
    5301           0 :     }
    5302             :   }
    5303           0 :   ~nsDisplayTableBlendMode() {
    5304             :     if (mAncestorFrame) {
    5305           0 :       mAncestorFrame->RemoveDisplayItem(this);
    5306             :     }
    5307             :   }
    5308           0 : 
    5309             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5310           0 :   {
    5311           0 :     return MakeDisplayItem<nsDisplayTableBlendMode>(aBuilder, *this);
    5312             :   }
    5313             : 
    5314           0 :   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
    5315           0 : 
    5316           0 :   virtual bool HasDeletedFrame() const override {
    5317             :     return !mAncestorFrame || nsDisplayBlendMode::HasDeletedFrame();
    5318           0 :   }
    5319           0 : 
    5320             :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    5321           0 :     if (aFrame == mAncestorFrame) {
    5322           0 :       mAncestorFrame = nullptr;
    5323           0 :     }
    5324           0 :     nsDisplayBlendMode::RemoveFrame(aFrame);
    5325             :   }
    5326             : 
    5327           0 :   virtual uint32_t GetPerFrameKey() const override {
    5328             :     return (mIndex << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
    5329             :            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    5330             :            nsDisplayItem::GetPerFrameKey();
    5331             :   }
    5332             : 
    5333             :   NS_DISPLAY_DECL_NAME("TableBlendMode", TYPE_TABLE_BLEND_MODE)
    5334             : 
    5335             : protected:
    5336             :   nsIFrame* mAncestorFrame;
    5337             :   TableType mTableType;
    5338             : };
    5339             : 
    5340             : class nsDisplayBlendContainer : public nsDisplayWrapList {
    5341             : public:
    5342             :     static nsDisplayBlendContainer*
    5343             :     CreateForMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5344             :                           nsDisplayList* aList,
    5345             :                           const ActiveScrolledRoot* aActiveScrolledRoot);
    5346             : 
    5347             :     static nsDisplayBlendContainer*
    5348             :     CreateForBackgroundBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5349             :                                  nsDisplayList* aList,
    5350           0 :                                  const ActiveScrolledRoot* aActiveScrolledRoot);
    5351             : 
    5352           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    5353           0 :     virtual ~nsDisplayBlendContainer();
    5354             : #endif
    5355             : 
    5356             :     virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5357             :     {
    5358             :       MOZ_COUNT_CTOR(nsDisplayBlendContainer);
    5359             :       return MakeDisplayItem<nsDisplayBlendContainer>(aBuilder, *this);
    5360             :     }
    5361             : 
    5362             :     virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5363             :                                                LayerManager* aManager,
    5364             :                                                const ContainerLayerParameters& aContainerParameters) override;
    5365             :     virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5366             :                                      LayerManager* aManager,
    5367             :                                      const ContainerLayerParameters& aParameters) override;
    5368           0 :     bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5369             :                                  mozilla::wr::IpcResourceUpdateQueue& aResources,
    5370             :                                  const StackingContextHelper& aSc,
    5371             :                                  mozilla::layers::WebRenderLayerManager* aManager,
    5372           0 :                                  nsDisplayListBuilder* aDisplayListBuilder) override;
    5373           0 : 
    5374             :     virtual bool CanMerge(const nsDisplayItem* aItem) const override
    5375             :     {
    5376           0 :       // Items for the same content element should be merged into a single
    5377             :       // compositing group.
    5378           0 :       return HasSameTypeAndClip(aItem) && HasSameContent(aItem)
    5379             :           && mIsForBackground == static_cast<const nsDisplayBlendContainer*>(aItem)->mIsForBackground;
    5380           0 :     }
    5381           0 : 
    5382             :     virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    5383           0 :     {
    5384             :       return false;
    5385             :     }
    5386             :     virtual uint32_t GetPerFrameKey() const override {
    5387             :       return (mIsForBackground ? 1 << TYPE_BITS : 0) | nsDisplayItem::GetPerFrameKey();
    5388             :     }
    5389             :     NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
    5390           0 : 
    5391             : protected:
    5392           0 :     nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5393           0 :                             nsDisplayList* aList,
    5394           0 :                             const ActiveScrolledRoot* aActiveScrolledRoot,
    5395             :                             bool aIsForBackground);
    5396             :     nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
    5397             :                             const nsDisplayBlendContainer& aOther)
    5398             :       : nsDisplayWrapList(aBuilder, aOther)
    5399             :       , mIsForBackground(aOther.mIsForBackground)
    5400             :     {}
    5401             : 
    5402             :     // Used to distinguish containers created at building stacking
    5403             :     // context or appending background.
    5404             :     bool mIsForBackground;
    5405             : };
    5406             : 
    5407             : class nsDisplayTableBlendContainer : public nsDisplayBlendContainer
    5408             : {
    5409             : public:
    5410           0 :   static nsDisplayTableBlendContainer*
    5411             :   CreateForBackgroundBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5412           0 :                                nsDisplayList* aList,
    5413             :                                const ActiveScrolledRoot* aActiveScrolledRoot,
    5414             :                                nsIFrame* aAncestorFrame);
    5415           0 : 
    5416             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5417           0 :   {
    5418           0 :     return MakeDisplayItem<nsDisplayTableBlendContainer>(aBuilder, *this);
    5419             :   }
    5420             : 
    5421           0 :   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
    5422           0 : 
    5423           0 :   virtual bool HasDeletedFrame() const override {
    5424             :     return !mAncestorFrame || nsDisplayBlendContainer::HasDeletedFrame();
    5425           0 :   }
    5426           0 : 
    5427             :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    5428           0 :     if (aFrame == mAncestorFrame) {
    5429           0 :       mAncestorFrame = nullptr;
    5430           0 :     }
    5431             :     nsDisplayBlendContainer::RemoveFrame(aFrame);
    5432             :   }
    5433           0 : 
    5434             :   virtual uint32_t GetPerFrameKey() const override {
    5435             :     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    5436             :            nsDisplayItem::GetPerFrameKey();
    5437             :   }
    5438             : 
    5439             :   NS_DISPLAY_DECL_NAME("TableBlendContainer", TYPE_TABLE_BLEND_CONTAINER)
    5440             : 
    5441             : protected:
    5442             :   nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5443             :                                nsDisplayList* aList,
    5444             :                                const ActiveScrolledRoot* aActiveScrolledRoot,
    5445             :                                bool aIsForBackground, nsIFrame* aAncestorFrame)
    5446             :     : nsDisplayBlendContainer(aBuilder, aFrame, aList, aActiveScrolledRoot, aIsForBackground)
    5447             :     , mAncestorFrame(aAncestorFrame)
    5448             :     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
    5449           0 :   {
    5450             :     if (aBuilder->IsRetainingDisplayList()) {
    5451           0 :       mAncestorFrame->AddDisplayItem(this);
    5452           0 :     }
    5453           0 :   }
    5454             : 
    5455           0 :   nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder,
    5456           0 :                                const nsDisplayTableBlendContainer& aOther)
    5457             :     : nsDisplayBlendContainer(aBuilder, aOther)
    5458           0 :     , mAncestorFrame(aOther.mAncestorFrame)
    5459           0 :     , mTableType(aOther.mTableType)
    5460           0 :   {
    5461           0 :     if (aBuilder->IsRetainingDisplayList()) {
    5462             :       mAncestorFrame->AddDisplayItem(this);
    5463           0 :     }
    5464             :   }
    5465             :   ~nsDisplayTableBlendContainer() {
    5466             :     if (mAncestorFrame) {
    5467             :       mAncestorFrame->RemoveDisplayItem(this);
    5468             :     }
    5469             :   }
    5470             : 
    5471             :   nsIFrame* mAncestorFrame;
    5472             :   TableType mTableType;
    5473             : };
    5474             : 
    5475             : 
    5476             : /**
    5477             :  * nsDisplayOwnLayer constructor flags. If we nest this class inside
    5478             :  * nsDisplayOwnLayer then we can't forward-declare it up at the top of this
    5479             :  * file and that makes it hard to use in all the places that we need to use it.
    5480             :  */
    5481             : enum class nsDisplayOwnLayerFlags {
    5482             :   eNone = 0,
    5483             :   eGenerateSubdocInvalidations = 1 << 0,
    5484             :   eGenerateScrollableLayer = 1 << 1,
    5485             : };
    5486             : 
    5487             : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsDisplayOwnLayerFlags)
    5488             : 
    5489             : /**
    5490             :  * A display item that has no purpose but to ensure its contents get
    5491             :  * their own layer.
    5492             :  */
    5493             : class nsDisplayOwnLayer : public nsDisplayWrapList {
    5494             : public:
    5495             :   typedef mozilla::layers::ScrollbarData ScrollbarData;
    5496             : 
    5497             :   /**
    5498             :    * @param aFlags eGenerateSubdocInvalidations :
    5499             :    * Add UserData to the created ContainerLayer, so that invalidations
    5500             :    * for this layer are send to our nsPresContext.
    5501             :    * eGenerateScrollableLayer : only valid on nsDisplaySubDocument (and
    5502             :    * subclasses), indicates this layer is to be a scrollable layer, so call
    5503             :    * ComputeFrameMetrics, etc.
    5504             :    * @param aScrollTarget when eVerticalScrollbar or eHorizontalScrollbar
    5505             :    * is set in the flags, this parameter should be the ViewID of the
    5506             :    * scrollable content this scrollbar is for.
    5507             :    */
    5508             :   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5509             :                     nsDisplayList* aList,
    5510             :                     const ActiveScrolledRoot* aActiveScrolledRoot,
    5511             :                     nsDisplayOwnLayerFlags aFlags = nsDisplayOwnLayerFlags::eNone,
    5512             :                     const ScrollbarData& aScrollbarData = ScrollbarData{},
    5513             :                     bool aForceActive = true,
    5514           0 :                     bool aClearClipChain = false);
    5515           0 : 
    5516           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    5517             :   virtual ~nsDisplayOwnLayer();
    5518           0 : #endif
    5519           0 : 
    5520             :   nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, const nsDisplayOwnLayer& aOther)
    5521           0 :     : nsDisplayWrapList(aBuilder, aOther)
    5522           0 :     , mFlags(aOther.mFlags)
    5523             :     , mScrollbarData(aOther.mScrollbarData)
    5524             :     , mForceActive(aOther.mForceActive)
    5525             :     , mWrAnimationId(aOther.mWrAnimationId)
    5526             :   {
    5527             :     MOZ_COUNT_CTOR(nsDisplayOwnLayer);
    5528             :   }
    5529             : 
    5530             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const override;
    5531             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5532             :                                              LayerManager* aManager,
    5533             :                                              const ContainerLayerParameters& aContainerParameters) override;
    5534             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5535             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    5536             :                                        const StackingContextHelper& aSc,
    5537             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    5538             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    5539           0 :   virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
    5540             :                                 mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
    5541             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5542           0 :                                    LayerManager* aManager,
    5543             :                                    const ContainerLayerParameters& aParameters) override;
    5544             : 
    5545           0 :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    5546             :   {
    5547           0 :     // Don't allow merging, each sublist must have its own layer
    5548             :     return false;
    5549             :   }
    5550             : 
    5551             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    5552             :   {
    5553             :     return false;
    5554             :   }
    5555           0 : 
    5556             :   void WriteDebugInfo(std::stringstream& aStream) override;
    5557             : 
    5558             :   nsDisplayOwnLayerFlags GetFlags() { return mFlags; }
    5559             :   bool IsScrollThumbLayer() const;
    5560             :   bool IsScrollbarContainer() const;
    5561             :   NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
    5562             : protected:
    5563             :   nsDisplayOwnLayerFlags mFlags;
    5564             : 
    5565             :   /**
    5566             :    * If this nsDisplayOwnLayer represents a scroll thumb layer or a
    5567             :    * scrollbar container layer, mScrollbarData stores information
    5568             :    * about the scrollbar. Otherwise, mScrollbarData will be
    5569             :    * default-constructed (in particular with mDirection == Nothing())
    5570             :    * and can be ignored.
    5571             :    */
    5572             :   ScrollbarData mScrollbarData;
    5573             :   bool mForceActive;
    5574             :   uint64_t mWrAnimationId;
    5575             : };
    5576             : 
    5577             : /**
    5578             :  * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer,
    5579             :  * except that it always populates the FrameMetrics instance on the ContainerLayer it
    5580             :  * builds.
    5581             :  */
    5582             : class nsDisplaySubDocument : public nsDisplayOwnLayer {
    5583             : public:
    5584             :   nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
    5585             :                        nsIFrame* aFrame, nsSubDocumentFrame* aSubDocFrame,
    5586             :                        nsDisplayList* aList, nsDisplayOwnLayerFlags aFlags);
    5587             :   virtual ~nsDisplaySubDocument();
    5588             : 
    5589             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    5590             :                            bool* aSnap) const override;
    5591             : 
    5592             :   virtual nsSubDocumentFrame* SubDocumentFrame() { return mSubDocFrame; }
    5593           0 : 
    5594             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    5595           0 :                                  nsRegion* aVisibleRegion) override;
    5596             : 
    5597             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const override;
    5598             : 
    5599             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    5600             :   {
    5601             :     return mShouldFlatten;
    5602             :   }
    5603             : 
    5604             :   void SetShouldFlattenAway(bool aShouldFlatten)
    5605             :   {
    5606             :     mShouldFlatten = aShouldFlatten;
    5607             :   }
    5608             : 
    5609             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5610             :                                    LayerManager* aManager,
    5611             :                                    const ContainerLayerParameters& aParameters) override
    5612             :   {
    5613             :     if (mShouldFlatten) {
    5614             :       return mozilla::LAYER_NONE;
    5615             :     }
    5616           0 :     return nsDisplayOwnLayer::GetLayerState(aBuilder, aManager, aParameters);
    5617             :   }
    5618             : 
    5619             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    5620             :                                    bool* aSnap) const override;
    5621             : 
    5622             :   NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
    5623             : 
    5624             :   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(LayerManager* aLayerManager,
    5625             :                                                            const ContainerLayerParameters& aContainerParameters);
    5626             : 
    5627             :   virtual nsIFrame* FrameForInvalidation() const override;
    5628             : 
    5629             :   virtual bool HasDeletedFrame() const override;
    5630             : 
    5631             :   virtual void RemoveFrame(nsIFrame* aFrame) override;
    5632             : 
    5633             :   void Disown();
    5634             : 
    5635             : protected:
    5636             :   ViewID mScrollParentId;
    5637             :   bool mForceDispatchToContentRegion;
    5638             :   bool mShouldFlatten;
    5639             :   nsSubDocumentFrame* mSubDocFrame;
    5640             : };
    5641             : 
    5642             : /**
    5643             :  * A display item for subdocuments to capture the resolution from the presShell
    5644             :  * and ensure that it gets applied to all the right elements. This item creates
    5645             :  * a container layer.
    5646             :  */
    5647             : class nsDisplayResolution : public nsDisplaySubDocument {
    5648             : public:
    5649             :   nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5650             :                       nsDisplayList* aList, nsDisplayOwnLayerFlags aFlags);
    5651             : #ifdef NS_BUILD_REFCNT_LOGGING
    5652             :   virtual ~nsDisplayResolution();
    5653           0 : #endif
    5654             :   virtual void HitTest(nsDisplayListBuilder* aBuilder,
    5655             :                        const nsRect& aRect,
    5656             :                        HitTestState* aState,
    5657             :                        nsTArray<nsIFrame*> *aOutFrames) override;
    5658             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5659             :                                              LayerManager* aManager,
    5660             :                                              const ContainerLayerParameters& aContainerParameters) override;
    5661             :   NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
    5662             : };
    5663             : 
    5664             : /**
    5665             :  * A display item used to represent sticky position elements. The contents
    5666             :  * gets its own layer and creates a stacking context, and the layer will have
    5667             :  * position-related metadata set on it.
    5668             :  */
    5669             : class nsDisplayStickyPosition : public nsDisplayOwnLayer {
    5670             : public:
    5671             :   nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5672             :                           nsDisplayList* aList,
    5673             :                           const ActiveScrolledRoot* aActiveScrolledRoot,
    5674             :                           const ActiveScrolledRoot* aContainerASR);
    5675             :   nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
    5676             :                           const nsDisplayStickyPosition& aOther)
    5677             :     : nsDisplayOwnLayer(aBuilder, aOther)
    5678             :     , mContainerASR(aOther.mContainerASR)
    5679             :   {}
    5680             : 
    5681             : #ifdef NS_BUILD_REFCNT_LOGGING
    5682             :   virtual ~nsDisplayStickyPosition();
    5683             : #endif
    5684             : 
    5685             :   void SetClipChain(const DisplayItemClipChain* aClipChain, bool aStore) override;
    5686             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5687           0 :   {
    5688             :     MOZ_COUNT_CTOR(nsDisplayStickyPosition);
    5689             :     return MakeDisplayItem<nsDisplayStickyPosition>(aBuilder, *this);
    5690             :   }
    5691             : 
    5692             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5693             :                                              LayerManager* aManager,
    5694             :                                              const ContainerLayerParameters& aContainerParameters) override;
    5695           0 :   NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
    5696             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5697             :                                    LayerManager* aManager,
    5698           0 :                                    const ContainerLayerParameters& aParameters) override
    5699             :   {
    5700             :     return mozilla::LAYER_ACTIVE;
    5701             :   }
    5702             : 
    5703             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    5704             :   {
    5705             :     // Items with the same fixed position frame can be merged.
    5706             :     return HasSameTypeAndClip(aItem) && mFrame == aItem->Frame();
    5707             :   }
    5708             : 
    5709             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5710             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    5711             :                                        const StackingContextHelper& aSc,
    5712             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    5713             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    5714             : 
    5715             :   const ActiveScrolledRoot* GetContainerASR() const
    5716             :   {
    5717             :     return mContainerASR;
    5718             :   }
    5719             : 
    5720             : private:
    5721             :   // This stores the ASR that this sticky container item would have assuming it
    5722             :   // has no fixed descendants. This may be the same as the ASR returned by
    5723             :   // GetActiveScrolledRoot(), or it may be a descendant of that.
    5724             :   RefPtr<const ActiveScrolledRoot> mContainerASR;
    5725           0 : };
    5726             : 
    5727           0 : class nsDisplayFixedPosition : public nsDisplayOwnLayer {
    5728             : public:
    5729           0 :   nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5730           0 :                          nsDisplayList* aList,
    5731             :                          const ActiveScrolledRoot* aActiveScrolledRoot,
    5732           0 :                          const ActiveScrolledRoot* aContainerASR);
    5733           0 :   nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
    5734             :                          const nsDisplayFixedPosition& aOther)
    5735             :     : nsDisplayOwnLayer(aBuilder, aOther)
    5736             :     , mAnimatedGeometryRootForScrollMetadata(aOther.mAnimatedGeometryRootForScrollMetadata)
    5737             :     , mIndex(aOther.mIndex)
    5738             :     , mIsFixedBackground(aOther.mIsFixedBackground)
    5739             :     , mContainerASR(aOther.mContainerASR)
    5740             :   {
    5741             :     MOZ_COUNT_CTOR(nsDisplayFixedPosition);
    5742             :   }
    5743             : 
    5744             :   static nsDisplayFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
    5745           0 :                                                           nsIFrame* aFrame,
    5746             :                                                           nsDisplayBackgroundImage* aImage,
    5747           0 :                                                           uint32_t aIndex);
    5748             : 
    5749             : 
    5750             : #ifdef NS_BUILD_REFCNT_LOGGING
    5751             :   virtual ~nsDisplayFixedPosition();
    5752             : #endif
    5753           0 : 
    5754           0 :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5755             :   {
    5756             :     return MakeDisplayItem<nsDisplayFixedPosition>(aBuilder, *this);
    5757             :   }
    5758           0 : 
    5759             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5760             :                                              LayerManager* aManager,
    5761           0 :                                              const ContainerLayerParameters& aContainerParameters) override;
    5762             :   NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_FIXED_POSITION)
    5763             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5764           0 :                                    LayerManager* aManager,
    5765             :                                    const ContainerLayerParameters& aParameters) override
    5766             :   {
    5767           0 :     return mozilla::LAYER_ACTIVE_FORCE;
    5768             :   }
    5769           0 : 
    5770             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    5771             :   {
    5772           0 :     // Items with the same fixed position frame can be merged.
    5773           0 :     return HasSameTypeAndClip(aItem) && mFrame == aItem->Frame();
    5774             :   }
    5775             : 
    5776           0 :   virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) const override
    5777           0 :   {
    5778             :     return mIsFixedBackground;
    5779             :   }
    5780             : 
    5781             :   virtual uint32_t GetPerFrameKey() const override {
    5782             :     return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
    5783             :   }
    5784             : 
    5785             :   AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
    5786             :     return mAnimatedGeometryRootForScrollMetadata;
    5787             :   }
    5788             : 
    5789             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    5790             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    5791             :                                        const StackingContextHelper& aSc,
    5792             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    5793             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    5794             :   virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
    5795             :                                 mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
    5796             : 
    5797             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    5798             : 
    5799             : protected:
    5800             :   // For background-attachment:fixed
    5801             :   nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5802             :                          nsDisplayList* aList, uint32_t aIndex);
    5803             :   void Init(nsDisplayListBuilder* aBuilder);
    5804             :   ViewID GetScrollTargetId();
    5805             : 
    5806             :   RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
    5807             :   uint32_t mIndex;
    5808             :   bool mIsFixedBackground;
    5809             :   RefPtr<const ActiveScrolledRoot> mContainerASR;
    5810             : };
    5811             : 
    5812           0 : class nsDisplayTableFixedPosition : public nsDisplayFixedPosition
    5813             : {
    5814           0 : public:
    5815             :   static nsDisplayTableFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
    5816             :                                                                nsIFrame* aFrame,
    5817           0 :                                                                nsDisplayBackgroundImage* aImage,
    5818             :                                                                uint32_t aIndex,
    5819           0 :                                                                nsIFrame* aAncestorFrame);
    5820           0 : 
    5821             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    5822             :   {
    5823           0 :     return MakeDisplayItem<nsDisplayTableFixedPosition>(aBuilder, *this);
    5824           0 :   }
    5825           0 : 
    5826             :   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
    5827           0 : 
    5828           0 :   virtual bool HasDeletedFrame() const override {
    5829             :     return !mAncestorFrame || nsDisplayFixedPosition::HasDeletedFrame();
    5830           0 :   }
    5831           0 : 
    5832           0 :   virtual void RemoveFrame(nsIFrame* aFrame) override {
    5833           0 :     if (aFrame == mAncestorFrame) {
    5834             :       mAncestorFrame = nullptr;
    5835             :     }
    5836           0 :     nsDisplayFixedPosition::RemoveFrame(aFrame);
    5837             :   }
    5838             : 
    5839             :   virtual uint32_t GetPerFrameKey() const override {
    5840             :     return (mIndex << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
    5841             :            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
    5842           0 :            nsDisplayItem::GetPerFrameKey();
    5843             :   }
    5844           0 : 
    5845           0 :   NS_DISPLAY_DECL_NAME("TableFixedPosition", TYPE_TABLE_FIXED_POSITION)
    5846           0 : protected:
    5847             :   nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5848           0 :                               nsDisplayList* aList, uint32_t aIndex,
    5849           0 :                               nsIFrame* aAncestorFrame);
    5850             : 
    5851           0 :   nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder,
    5852           0 :                               const nsDisplayTableFixedPosition& aOther)
    5853           0 :     : nsDisplayFixedPosition(aBuilder, aOther)
    5854           0 :     , mAncestorFrame(aOther.mAncestorFrame)
    5855             :     , mTableType(aOther.mTableType)
    5856           0 :   {
    5857             :     if (aBuilder->IsRetainingDisplayList()) {
    5858             :       mAncestorFrame->AddDisplayItem(this);
    5859             :     }
    5860             :   }
    5861             :   ~nsDisplayTableFixedPosition() {
    5862             :     if (mAncestorFrame) {
    5863             :       mAncestorFrame->RemoveDisplayItem(this);
    5864             :     }
    5865             :   }
    5866             : 
    5867             :   nsIFrame* mAncestorFrame;
    5868             :   TableType mTableType;
    5869             : };
    5870             : 
    5871             : /**
    5872           0 :  * This creates an empty scrollable layer. It has no child layers.
    5873             :  * It is used to record the existence of a scrollable frame in the layer
    5874             :  * tree.
    5875             :  */
    5876             : class nsDisplayScrollInfoLayer : public nsDisplayWrapList
    5877             : {
    5878             : public:
    5879             :   nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
    5880             :                            nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
    5881             :   NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
    5882             : 
    5883           0 : 
    5884             : #ifdef NS_BUILD_REFCNT_LOGGING
    5885           0 :   virtual ~nsDisplayScrollInfoLayer();
    5886             : #endif
    5887             : 
    5888           0 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    5889             :                                              LayerManager* aManager,
    5890             :                                              const ContainerLayerParameters& aContainerParameters) override;
    5891           0 : 
    5892           0 :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const override
    5893             :   {
    5894             :     return true;
    5895             :   }
    5896             : 
    5897             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    5898             :                                    bool* aSnap) const override
    5899           0 :   {
    5900             :     *aSnap = false;
    5901           0 :     return nsRegion();
    5902             :   }
    5903             : 
    5904             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5905             :                                    LayerManager* aManager,
    5906             :                                    const ContainerLayerParameters& aParameters) override;
    5907             : 
    5908             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
    5909             :   {
    5910             :     return false;
    5911             :   }
    5912             : 
    5913             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    5914             : 
    5915             :   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(LayerManager* aLayerManager,
    5916             :                                                            const ContainerLayerParameters& aContainerParameters);
    5917             : 
    5918             :   virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
    5919             :                                 mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
    5920             : 
    5921             : protected:
    5922             :   nsIFrame* mScrollFrame;
    5923             :   nsIFrame* mScrolledFrame;
    5924             :   ViewID mScrollParentId;
    5925             : };
    5926             : 
    5927             : /**
    5928             :  * nsDisplayZoom is used for subdocuments that have a different full zoom than
    5929             :  * their parent documents. This item creates a container layer.
    5930             :  */
    5931             : class nsDisplayZoom : public nsDisplaySubDocument {
    5932             : public:
    5933             :   /**
    5934             :    * @param aFrame is the root frame of the subdocument.
    5935             :    * @param aList contains the display items for the subdocument.
    5936             :    * @param aAPD is the app units per dev pixel ratio of the subdocument.
    5937             :    * @param aParentAPD is the app units per dev pixel ratio of the parent
    5938             :    * document.
    5939             :    * @param aFlags eGenerateSubdocInvalidations :
    5940             :    * Add UserData to the created ContainerLayer, so that invalidations
    5941             :    * for this layer are send to our nsPresContext.
    5942             :    */
    5943             :   nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5944             :                 nsDisplayList* aList,
    5945             :                 int32_t aAPD, int32_t aParentAPD,
    5946             :                 nsDisplayOwnLayerFlags aFlags = nsDisplayOwnLayerFlags::eNone);
    5947             : #ifdef NS_BUILD_REFCNT_LOGGING
    5948             :   virtual ~nsDisplayZoom();
    5949             : #endif
    5950             : 
    5951             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    5952             :                            bool* aSnap) const override;
    5953             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    5954           0 :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
    5955             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    5956             :                                  nsRegion* aVisibleRegion) override;
    5957             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    5958             :                                    LayerManager* aManager,
    5959             :                                    const ContainerLayerParameters& aParameters) override
    5960             :   {
    5961             :     return mozilla::LAYER_ACTIVE;
    5962             :   }
    5963             :   NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
    5964             : 
    5965             :   // Get the app units per dev pixel ratio of the child document.
    5966             :   int32_t GetChildAppUnitsPerDevPixel() { return mAPD; }
    5967             :   // Get the app units per dev pixel ratio of the parent document.
    5968             :   int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; }
    5969             : 
    5970             : private:
    5971             :   int32_t mAPD, mParentAPD;
    5972             : };
    5973             : 
    5974             : class nsDisplaySVGEffects: public nsDisplayWrapList {
    5975             : public:
    5976             :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5977             :                       nsDisplayList* aList, bool aHandleOpacity,
    5978             :                       const ActiveScrolledRoot* aActiveScrolledRoot,
    5979             :                       bool aClearClipChain = false);
    5980             :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    5981             :                       nsDisplayList* aList, bool aHandleOpacity);
    5982             : #ifdef NS_BUILD_REFCNT_LOGGING
    5983             :   virtual ~nsDisplaySVGEffects();
    5984             : #endif
    5985             : 
    5986             :   nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
    5987             :                       const nsDisplaySVGEffects& aOther)
    5988             :     : nsDisplayWrapList(aBuilder, aOther)
    5989             :     , mEffectsBounds(aOther.mEffectsBounds)
    5990             :     , mHandleOpacity(aOther.mHandleOpacity)
    5991             :   {
    5992           0 :     MOZ_COUNT_CTOR(nsDisplaySVGEffects);
    5993           0 :   }
    5994             : 
    5995             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    5996             :                                    bool* aSnap) const override;
    5997             :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    5998             :                        HitTestState* aState,
    5999             :                        nsTArray<nsIFrame*> *aOutFrames) override;
    6000             : 
    6001             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
    6002             :     return false;
    6003             :   }
    6004             : 
    6005             :   bool ShouldHandleOpacity() {
    6006             :     return mHandleOpacity;
    6007             :   }
    6008             : 
    6009             :   gfxRect BBoxInUserSpace() const;
    6010             :   gfxPoint UserSpaceOffset() const;
    6011             : 
    6012             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6013             :                                          const nsDisplayItemGeometry* aGeometry,
    6014             :                                          nsRegion* aInvalidRegion) const override;
    6015             : protected:
    6016             :   bool ValidateSVGFrame();
    6017             : 
    6018             :   // relative to mFrame
    6019             :   nsRect mEffectsBounds;
    6020             :   // True if we need to handle css opacity in this display item.
    6021             :   bool mHandleOpacity;
    6022             : };
    6023             : 
    6024             : /**
    6025             :  * A display item to paint a stacking context with mask and clip effects
    6026             :  * set by the stacking context root frame's style.
    6027             :  */
    6028             : class nsDisplayMask : public nsDisplaySVGEffects {
    6029             : public:
    6030             :   typedef mozilla::layers::ImageLayer ImageLayer;
    6031             : 
    6032             :   nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    6033             :                 nsDisplayList* aList, bool aHandleOpacity,
    6034             :                 const ActiveScrolledRoot* aActiveScrolledRoot);
    6035             :   nsDisplayMask(nsDisplayListBuilder* aBuilder,
    6036             :                 const nsDisplayMask& aOther)
    6037             :     : nsDisplaySVGEffects(aBuilder, aOther)
    6038             :     , mDestRects(aOther.mDestRects)
    6039             :   {}
    6040             : #ifdef NS_BUILD_REFCNT_LOGGING
    6041           0 :   virtual ~nsDisplayMask();
    6042             : #endif
    6043             : 
    6044             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    6045             :   {
    6046             :     MOZ_COUNT_CTOR(nsDisplayMask);
    6047             :     return MakeDisplayItem<nsDisplayMask>(aBuilder, *this);
    6048             :   }
    6049             : 
    6050             :   NS_DISPLAY_DECL_NAME("Mask", TYPE_MASK)
    6051             : 
    6052             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override;
    6053             : 
    6054             :   virtual void Merge(const nsDisplayItem* aItem) override
    6055             :   {
    6056             :     nsDisplayWrapList::Merge(aItem);
    6057             : 
    6058             :     const nsDisplayMask* other = static_cast<const nsDisplayMask*>(aItem);
    6059             :     mEffectsBounds.UnionRect(mEffectsBounds,
    6060             :       other->mEffectsBounds + other->mFrame->GetOffsetTo(mFrame));
    6061             :   }
    6062             : 
    6063             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    6064           0 :                                              LayerManager* aManager,
    6065             :                                              const ContainerLayerParameters& aContainerParameters) override;
    6066           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    6067             :                                    LayerManager* aManager,
    6068             :                                    const ContainerLayerParameters& aParameters) override;
    6069             : 
    6070             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    6071             :                                  nsRegion* aVisibleRegion) override;
    6072             : 
    6073             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    6074             :   {
    6075             :     return new nsDisplayMaskGeometry(this, aBuilder);
    6076             :   }
    6077             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6078             :                                          const nsDisplayItemGeometry* aGeometry,
    6079             :                                          nsRegion* aInvalidRegion) const override;
    6080             : #ifdef MOZ_DUMP_PAINTING
    6081             :   void PrintEffects(nsACString& aTo);
    6082             : #endif
    6083             : 
    6084             :   void PaintAsLayer(nsDisplayListBuilder* aBuilder,
    6085             :                     gfxContext* aCtx,
    6086             :                     LayerManager* aManager);
    6087             : 
    6088             :   /*
    6089             :    * Paint mask onto aMaskContext in mFrame's coordinate space and
    6090             :    * return whether the mask layer was painted successfully.
    6091             :    */
    6092             :   bool PaintMask(nsDisplayListBuilder* aBuilder, gfxContext* aMaskContext);
    6093             : 
    6094             :   const nsTArray<nsRect>& GetDestRects()
    6095             :   {
    6096             :     return mDestRects;
    6097             :   }
    6098             : 
    6099             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    6100             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    6101             :                                        const StackingContextHelper& aSc,
    6102             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    6103             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    6104             : 
    6105             :   virtual mozilla::Maybe<nsRect> GetClipWithRespectToASR(
    6106             :       nsDisplayListBuilder* aBuilder,
    6107             :       const ActiveScrolledRoot* aASR) const override;
    6108             : private:
    6109             :   // According to mask property and the capability of aManager, determine
    6110             :   // whether we can paint the mask onto a dedicate mask layer.
    6111             :   bool CanPaintOnMaskLayer(LayerManager* aManager);
    6112             : 
    6113             :   nsTArray<nsRect> mDestRects;
    6114             : };
    6115             : 
    6116             : /**
    6117             :  * A display item to paint a stacking context with filter effects set by the
    6118             :  * stacking context root frame's style.
    6119             :  */
    6120             : class nsDisplayFilter : public nsDisplaySVGEffects {
    6121             : public:
    6122             :   nsDisplayFilter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    6123             :                   nsDisplayList* aList, bool aHandleOpacity);
    6124             :   nsDisplayFilter(nsDisplayListBuilder* aBuilder,
    6125             :                   const nsDisplayFilter& aOther)
    6126             :     : nsDisplaySVGEffects(aBuilder, aOther)
    6127             :     , mEffectsBounds(aOther.mEffectsBounds)
    6128             :   {}
    6129             : #ifdef NS_BUILD_REFCNT_LOGGING
    6130           0 :   virtual ~nsDisplayFilter();
    6131             : #endif
    6132           0 : 
    6133             :   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
    6134             :   {
    6135             :     MOZ_COUNT_CTOR(nsDisplayFilter);
    6136           0 :     return MakeDisplayItem<nsDisplayFilter>(aBuilder, *this);
    6137             :   }
    6138             : 
    6139             :   NS_DISPLAY_DECL_NAME("Filter", TYPE_FILTER)
    6140             : 
    6141             :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    6142             :   {
    6143             :     // Items for the same content element should be merged into a single
    6144             :     // compositing group.
    6145             :     return HasSameTypeAndClip(aItem) && HasSameContent(aItem);
    6146             :   }
    6147             : 
    6148             :   virtual void Merge(const nsDisplayItem* aItem) override
    6149             :   {
    6150             :     nsDisplayWrapList::Merge(aItem);
    6151             : 
    6152             :     const nsDisplayFilter* other = static_cast<const nsDisplayFilter*>(aItem);
    6153             :     mEffectsBounds.UnionRect(mEffectsBounds,
    6154           0 :       other->mEffectsBounds + other->mFrame->GetOffsetTo(mFrame));
    6155             :   }
    6156             : 
    6157           0 :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    6158           0 :                                              LayerManager* aManager,
    6159             :                                              const ContainerLayerParameters& aContainerParameters) override;
    6160             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    6161             :                                    LayerManager* aManager,
    6162           0 :                                    const ContainerLayerParameters& aParameters) override;
    6163             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    6164           0 :                            bool* aSnap) const override
    6165             :   {
    6166             :     *aSnap = false;
    6167             :     return mEffectsBounds + ToReferenceFrame();
    6168             :   }
    6169             :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    6170             :                                  nsRegion* aVisibleRegion) override;
    6171             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
    6172             :   {
    6173             :     return new nsDisplayFilterGeometry(this, aBuilder);
    6174             :   }
    6175             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6176             :                                          const nsDisplayItemGeometry* aGeometry,
    6177             :                                          nsRegion* aInvalidRegion) const override;
    6178             : #ifdef MOZ_DUMP_PAINTING
    6179             :   void PrintEffects(nsACString& aTo);
    6180             : #endif
    6181             : 
    6182             :   void PaintAsLayer(nsDisplayListBuilder* aBuilder,
    6183             :                     gfxContext* aCtx,
    6184             :                     LayerManager* aManager);
    6185             : 
    6186             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    6187             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    6188             :                                        const StackingContextHelper& aSc,
    6189             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    6190             :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    6191             : 
    6192             : private:
    6193             :   // relative to mFrame
    6194             :   nsRect mEffectsBounds;
    6195             : };
    6196             : 
    6197             : /* A display item that applies a transformation to all of its descendant
    6198             :  * elements.  This wrapper should only be used if there is a transform applied
    6199             :  * to the root element.
    6200             :  *
    6201             :  * The reason that a "bounds" rect is involved in transform calculations is
    6202             :  * because CSS-transforms allow percentage values for the x and y components
    6203             :  * of <translation-value>s, where percentages are percentages of the element's
    6204             :  * border box.
    6205             :  *
    6206             :  * INVARIANT: The wrapped frame is transformed or we supplied a transform getter
    6207             :  * function.
    6208             :  * INVARIANT: The wrapped frame is non-null.
    6209             :  */
    6210             : class nsDisplayTransform: public nsDisplayItem
    6211             : {
    6212             :   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
    6213             :   typedef mozilla::gfx::Matrix4x4Flagged Matrix4x4Flagged;
    6214             :   typedef mozilla::gfx::Point3D Point3D;
    6215           0 : 
    6216             :   /*
    6217           0 :    * Avoid doing UpdateBounds() during construction.
    6218             :    */
    6219             :   class StoreList : public nsDisplayWrapList {
    6220           0 :   public:
    6221           0 :     StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    6222             :               nsDisplayList* aList)
    6223           0 :       : nsDisplayWrapList(aBuilder, aFrame, aList, true) {}
    6224             :     virtual ~StoreList() = default;
    6225           0 : 
    6226             :     virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override {
    6227           0 :       // For extending 3d rendering context, the bounds would be
    6228           0 :       // updated by DoUpdateBoundsPreserves3D(), not here.
    6229           0 :       if (!mFrame->Extend3DContext()) {
    6230             :         nsDisplayWrapList::UpdateBounds(aBuilder);
    6231           0 :       }
    6232           0 :     }
    6233             :     void ForceUpdateBounds(nsDisplayListBuilder* aBuilder) {
    6234             :       nsDisplayWrapList::UpdateBounds(aBuilder);
    6235             :     }
    6236             :     virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    6237             :       for (nsDisplayItem *i = mList.GetBottom(); i; i = i->GetAbove()) {
    6238             :         i->DoUpdateBoundsPreserves3D(aBuilder);
    6239             :       }
    6240             :       nsDisplayWrapList::UpdateBounds(aBuilder);
    6241             :     }
    6242             :   };
    6243             : 
    6244             : public:
    6245             :   enum PrerenderDecision {
    6246             :     NoPrerender,
    6247             :     FullPrerender,
    6248             :     PartialPrerender
    6249             :   };
    6250             : 
    6251             :   /**
    6252             :    * Returns a matrix (in pixels) for the current frame. The matrix should be relative to
    6253             :    * the current frame's coordinate space.
    6254             :    *
    6255             :    * @param aFrame The frame to compute the transform for.
    6256             :    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    6257             :    */
    6258             :   typedef Matrix4x4 (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel);
    6259             : 
    6260             :   /* Constructor accepts a display list, empties it, and wraps it up.  It also
    6261             :    * ferries the underlying frame to the nsDisplayItem constructor.
    6262             :    */
    6263             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    6264             :                      nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
    6265           0 :                      uint32_t aIndex = 0, bool aAllowAsyncAnimation = false);
    6266           0 :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    6267           0 :                      nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
    6268           0 :                      ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
    6269             :   nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
    6270             :                      nsDisplayList *aList, const nsRect& aChildrenBuildingRect,
    6271           0 :                      const Matrix4x4& aTransform, uint32_t aIndex = 0);
    6272             : 
    6273           0 : #ifdef NS_BUILD_REFCNT_LOGGING
    6274           0 :   virtual ~nsDisplayTransform()
    6275           0 :   {
    6276             :     MOZ_COUNT_DTOR(nsDisplayTransform);
    6277             :   }
    6278           0 : #endif
    6279           0 : 
    6280             :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
    6281             :   {
    6282           0 :     mHasBounds = false;
    6283             :     if (IsTransformSeparator()) {
    6284           0 :       mStoredList.ForceUpdateBounds(aBuilder);
    6285           0 :       return;
    6286           0 :     }
    6287             :     mStoredList.UpdateBounds(aBuilder);
    6288           0 :     UpdateBoundsFor3D(aBuilder);
    6289             :   }
    6290           0 : 
    6291             :   virtual void Destroy(nsDisplayListBuilder* aBuilder) override
    6292           0 :   {
    6293           0 :     mStoredList.GetChildren()->DeleteAll(aBuilder);
    6294             :     nsDisplayItem::Destroy(aBuilder);
    6295           0 :   }
    6296             : 
    6297             :   NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
    6298           0 : 
    6299             :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
    6300           0 :   {
    6301             :     if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
    6302             :       return nsRect();
    6303           0 :     bool snap;
    6304             :     return GetBounds(aBuilder, &snap);
    6305           0 :   }
    6306           0 : 
    6307           0 :   virtual RetainedDisplayList* GetChildren() const override
    6308             :   {
    6309             :     return mStoredList.GetChildren();
    6310             :   }
    6311             : 
    6312             :   virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override
    6313             :   {
    6314             :     nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
    6315             :     mStoredList.SetActiveScrolledRoot(aActiveScrolledRoot);
    6316             :   }
    6317             : 
    6318             :   virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
    6319             :                        HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) override;
    6320             :   virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder,
    6321             :                            bool* aSnap) const override;
    6322             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
    6323             :                                    bool* aSnap) const override;
    6324             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    6325             :                                    LayerManager* aManager,
    6326             :                                    const ContainerLayerParameters& aParameters) override;
    6327             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    6328             :                                              LayerManager* aManager,
    6329             :                                              const ContainerLayerParameters& aContainerParameters) override;
    6330             :   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    6331             :                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
    6332           0 :                                        const StackingContextHelper& aSc,
    6333             :                                        mozilla::layers::WebRenderLayerManager* aManager,
    6334           0 :                                        nsDisplayListBuilder* aDisplayListBuilder) override;
    6335             :   virtual bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
    6336             :                                 mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
    6337           0 :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const override;
    6338           0 :   virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
    6339             :                                  nsRegion *aVisibleRegion) override;
    6340             : 
    6341           0 :   virtual bool CanMerge(const nsDisplayItem* aItem) const override
    6342             :   {
    6343             :     return false;
    6344             :   }
    6345             : 
    6346           0 :   virtual uint32_t GetPerFrameKey() const override {
    6347             :     return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
    6348           0 :   }
    6349             : 
    6350             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6351             :                                          const nsDisplayItemGeometry* aGeometry,
    6352           0 :                                          nsRegion* aInvalidRegion) const override
    6353           0 :   {
    6354             :     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
    6355           0 :   }
    6356             : 
    6357             :   virtual const nsIFrame* ReferenceFrameForChildren() const override {
    6358           0 :     // If we were created using a transform-getter, then we don't
    6359           0 :     // belong to a transformed frame, and aren't a reference frame
    6360             :     // for our children.
    6361             :     if (!mTransformGetter) {
    6362           0 :       return mFrame;
    6363             :     }
    6364           0 :     return nsDisplayItem::ReferenceFrameForChildren();
    6365             :   }
    6366             : 
    6367             :   AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
    6368             :     return mAnimatedGeometryRootForScrollMetadata;
    6369             :   }
    6370             : 
    6371             :   virtual const nsRect& GetBuildingRectForChildren() const override
    6372             :   {
    6373             :     return mChildrenBuildingRect;
    6374             :   }
    6375             : 
    6376             :   enum {
    6377             :     INDEX_MAX = UINT32_MAX >> TYPE_BITS
    6378             :   };
    6379             : 
    6380             :   /**
    6381             :    * We include the perspective matrix from our containing block for the
    6382             :    * purposes of visibility calculations, but we exclude it from the transform
    6383             :    * we set on the layer (for rendering), since there will be an
    6384             :    * nsDisplayPerspective created for that.
    6385             :    */
    6386             :   const Matrix4x4Flagged& GetTransform() const;
    6387             :   const Matrix4x4Flagged& GetInverseTransform() const;
    6388             : 
    6389             :   Matrix4x4 GetTransformForRendering(mozilla::LayoutDevicePoint* aOutOrigin = nullptr);
    6390             : 
    6391             :   /**
    6392             :    * Return the transform that is aggregation of all transform on the
    6393             :    * preserves3d chain.
    6394             :    */
    6395             :   const Matrix4x4& GetAccumulatedPreserved3DTransform(nsDisplayListBuilder* aBuilder);
    6396             : 
    6397             :   float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
    6398             : 
    6399             :   /**
    6400             :    * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
    6401             :    * space) and returns the smallest rectangle (in aFrame's coordinate space)
    6402             :    * containing the transformed image of that rectangle.  That is, it takes
    6403             :    * the four corners of the rectangle, transforms them according to the
    6404             :    * matrix associated with the specified frame, then returns the smallest
    6405             :    * rectangle containing the four transformed points.
    6406             :    *
    6407             :    * @param untransformedBounds The rectangle (in app units) to transform.
    6408             :    * @param aFrame The frame whose transformation should be applied.  This
    6409             :    *        function raises an assertion if aFrame is null or doesn't have a
    6410             :    *        transform applied to it.
    6411             :    * @param aOrigin The origin of the transform relative to aFrame's local
    6412             :    *        coordinate space.
    6413             :    * @param aBoundsOverride (optional) Rather than using the frame's computed
    6414             :    *        bounding rect as frame bounds, use this rectangle instead.  Pass
    6415             :    *        nullptr (or nothing at all) to use the default.
    6416             :    */
    6417             :   static nsRect TransformRect(const nsRect &aUntransformedBounds,
    6418             :                               const nsIFrame* aFrame,
    6419             :                               const nsRect* aBoundsOverride = nullptr);
    6420             : 
    6421             :   /* UntransformRect is like TransformRect, except that it inverts the
    6422             :    * transform.
    6423             :    */
    6424             :   static bool UntransformRect(const nsRect &aTransformedBounds,
    6425             :                               const nsRect &aChildBounds,
    6426             :                               const nsIFrame* aFrame,
    6427             :                               nsRect *aOutRect);
    6428             : 
    6429             :   bool UntransformRect(nsDisplayListBuilder* aBuilder,
    6430             :                        const nsRect& aRect,
    6431             :                        nsRect* aOutRect) const;
    6432             :   bool UntransformBuildingRect(nsDisplayListBuilder* aBuilder,
    6433             :                                nsRect* aOutRect) const
    6434             :   {
    6435             :     return UntransformRect(aBuilder, GetBuildingRect(), aOutRect);
    6436             : 
    6437             :   }
    6438             :   bool UntransformPaintRect(nsDisplayListBuilder* aBuilder,
    6439             :                             nsRect* aOutRect) const
    6440             :   {
    6441             :     return UntransformRect(aBuilder, GetPaintRect(), aOutRect);
    6442             :   }
    6443             : 
    6444             :   static Point3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
    6445             :                                            float aAppUnitsPerPixel,
    6446             :                                            const nsRect* aBoundsOverride);
    6447             : 
    6448             :   /*
    6449             :    * Returns true if aFrame has perspective applied from its containing
    6450             :    * block.
    6451             :    * Returns the matrix to append to apply the persective (taking
    6452           0 :    * perspective-origin into account), relative to aFrames coordinate
    6453             :    * space).
    6454             :    * aOutMatrix is assumed to be the identity matrix, and isn't explicitly
    6455             :    * cleared.
    6456             :    */
    6457             :   static bool ComputePerspectiveMatrix(const nsIFrame* aFrame,
    6458             :                                        float aAppUnitsPerPixel,
    6459             :                                        Matrix4x4& aOutMatrix);
    6460           0 : 
    6461           0 :   struct FrameTransformProperties
    6462           0 :   {
    6463             :     FrameTransformProperties(const nsIFrame* aFrame,
    6464             :                              float aAppUnitsPerPixel,
    6465             :                              const nsRect* aBoundsOverride);
    6466             :     FrameTransformProperties(RefPtr<const nsCSSValueSharedList>&&
    6467             :                                aTransformList,
    6468             :                              const Point3D& aToTransformOrigin)
    6469             :       : mFrame(nullptr)
    6470             :       , mTransformList(std::move(aTransformList))
    6471             :       , mToTransformOrigin(aToTransformOrigin)
    6472             :     {}
    6473             : 
    6474             :     const nsIFrame* mFrame;
    6475             :     const RefPtr<const nsCSSValueSharedList> mTransformList;
    6476             :     const Point3D mToTransformOrigin;
    6477             :   };
    6478             : 
    6479             :   /**
    6480             :    * Given a frame with the -moz-transform property or an SVG transform,
    6481             :    * returns the transformation matrix for that frame.
    6482             :    *
    6483             :    * @param aFrame The frame to get the matrix from.
    6484             :    * @param aOrigin Relative to which point this transform should be applied.
    6485             :    * @param aAppUnitsPerPixel The number of app units per graphics unit.
    6486             :    * @param aBoundsOverride [optional] If this is nullptr (the default), the
    6487             :    *        computation will use the value of TransformReferenceBox(aFrame).
    6488             :    *        Otherwise, it will use the value of aBoundsOverride.  This is
    6489             :    *        mostly for internal use and in most cases you will not need to
    6490             :    *        specify a value.
    6491             :    * @param aFlags OFFSET_BY_ORIGIN The resulting matrix will be translated
    6492             :    *        by aOrigin. This translation is applied *before* the CSS transform.
    6493             :    * @param aFlags INCLUDE_PRESERVE3D_ANCESTORS The computed transform will
    6494             :    *        include the transform of any ancestors participating in the same
    6495             :    *        3d rendering context.
    6496             :    * @param aFlags INCLUDE_PERSPECTIVE The resulting matrix will include the
    6497             :    *        perspective transform from the containing block if applicable.
    6498             :    */
    6499             :   enum {
    6500             :     OFFSET_BY_ORIGIN = 1 << 0,
    6501             :     INCLUDE_PRESERVE3D_ANCESTORS = 1 << 1,
    6502             :     INCLUDE_PERSPECTIVE = 1 << 2,
    6503             :   };
    6504             :   static Matrix4x4 GetResultingTransformMatrix(const nsIFrame* aFrame,
    6505             :                                                const nsPoint& aOrigin,
    6506             :                                                float aAppUnitsPerPixel,
    6507             :                                                uint32_t aFlags,
    6508             :                                                const nsRect* aBoundsOverride = nullptr);
    6509             :   static Matrix4x4 GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
    6510             :                                                const nsPoint& aOrigin,
    6511             :                                                float aAppUnitsPerPixel,
    6512             :                                                uint32_t aFlags,
    6513             :                                                const nsRect* aBoundsOverride = nullptr);
    6514             :   /**
    6515             :    * Decide whether we should prerender some or all of the contents of the
    6516             :    * transformed frame even when it's not completely visible (yet).
    6517             :    * Return FullPrerender if the entire contents should be prerendered,
    6518             :    * PartialPrerender if some but not all of the contents should be prerendered,
    6519             :    * or NoPrerender if only the visible area should be rendered.
    6520             :    * |aDirtyRect| is updated to the area that should be prerendered.
    6521             :    */
    6522             :   static PrerenderDecision ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
    6523             :                                                              nsIFrame* aFrame,
    6524             :                                                              nsRect* aDirtyRect);
    6525             :   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
    6526           0 : 
    6527           0 :   bool MayBeAnimated(nsDisplayListBuilder* aBuilder) const;
    6528             : 
    6529             :   virtual void WriteDebugInfo(std::stringstream& aStream) override;
    6530           0 : 
    6531           0 :   // Force the layer created for this item not to extend 3D context.
    6532             :   // See nsIFrame::BuildDisplayListForStackingContext()
    6533             :   void SetNoExtendContext() { mNoExtendContext = true; }
    6534             : 
    6535             :   virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    6536             :     MOZ_ASSERT(mFrame->Combines3DTransformWithAncestors() ||
    6537             :                IsTransformSeparator());
    6538             :     // Updating is not going through to child 3D context.
    6539           0 :     ComputeBounds(aBuilder);
    6540           0 :   }
    6541           0 : 
    6542           0 :   /**
    6543             :    * This function updates bounds for items with a frame establishing
    6544           0 :    * 3D rendering context.
    6545             :    *
    6546             :    * \see nsDisplayItem::DoUpdateBoundsPreserves3D()
    6547             :    */
    6548           0 :   void UpdateBoundsFor3D(nsDisplayListBuilder* aBuilder) {
    6549           0 :     if (!mFrame->Extend3DContext() ||
    6550           0 :         mFrame->Combines3DTransformWithAncestors() ||
    6551           0 :         IsTransformSeparator()) {
    6552           0 :       // Not an establisher of a 3D rendering context.
    6553           0 :       return;
    6554             :     }
    6555             :     // Always start updating from an establisher of a 3D rendering context.
    6556             : 
    6557             :     nsDisplayListBuilder::AutoAccumulateRect accRect(aBuilder);
    6558             :     nsDisplayListBuilder::AutoAccumulateTransform accTransform(aBuilder);
    6559             :     accTransform.StartRoot();
    6560             :     ComputeBounds(aBuilder);
    6561             :     mBounds = aBuilder->GetAccumulatedRect();
    6562             :     mHasBounds = true;
    6563             :   }
    6564             : 
    6565             :   /**
    6566             :    * This item is an additional item as the boundary between parent
    6567             :    * and child 3D rendering context.
    6568             :    * \see nsIFrame::BuildDisplayListForStackingContext().
    6569             :    */
    6570             :   bool IsTransformSeparator() { return mIsTransformSeparator; }
    6571             :   /**
    6572             :    * This item is the boundary between parent and child 3D rendering
    6573             :    * context.
    6574             :    */
    6575             :   bool IsLeafOf3DContext() {
    6576             :     return (IsTransformSeparator() ||
    6577             :             (!mFrame->Extend3DContext() &&
    6578             :              mFrame->Combines3DTransformWithAncestors()));
    6579             :   }
    6580           0 :   /**
    6581             :    * The backing frame of this item participates a 3D rendering
    6582           0 :    * context.
    6583           0 :    */
    6584           0 :   bool IsParticipating3DContext() {
    6585             :     return mFrame->Extend3DContext() ||
    6586             :       mFrame->Combines3DTransformWithAncestors();
    6587             :   }
    6588             : 
    6589             :   virtual void RemoveFrame(nsIFrame* aFrame) override
    6590             :   {
    6591             :     nsDisplayItem::RemoveFrame(aFrame);
    6592             :     mStoredList.RemoveFrame(aFrame);
    6593             :   }
    6594             : 
    6595             : private:
    6596             :   void ComputeBounds(nsDisplayListBuilder* aBuilder);
    6597             :   void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
    6598             :   void Init(nsDisplayListBuilder* aBuilder);
    6599             : 
    6600             :   static Matrix4x4 GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
    6601             :                                                        const nsPoint& aOrigin,
    6602             :                                                        float aAppUnitsPerPixel,
    6603             :                                                        uint32_t aFlags,
    6604             :                                                        const nsRect* aBoundsOverride);
    6605             : 
    6606             :   StoreList mStoredList;
    6607             :   mutable mozilla::Maybe<Matrix4x4Flagged> mTransform;
    6608             :   mutable mozilla::Maybe<Matrix4x4Flagged> mInverseTransform;
    6609             :   // Accumulated transform of ancestors on the preserves-3d chain.
    6610             :   Matrix4x4 mTransformPreserves3D;
    6611             :   ComputeTransformFunction mTransformGetter;
    6612             :   RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForChildren;
    6613             :   RefPtr<AnimatedGeometryRoot> mAnimatedGeometryRootForScrollMetadata;
    6614             :   nsRect mChildrenBuildingRect;
    6615             :   uint32_t mIndex;
    6616             :   mutable nsRect mBounds;
    6617             :   // True for mBounds is valid.
    6618             :   mutable bool mHasBounds;
    6619             :   // Be forced not to extend 3D context.  Since we don't create a
    6620             :   // transform item, a container layer, for every frames in a
    6621             :   // preserves3d context, the transform items of a child preserves3d
    6622             :   // context may extend the parent context not intented if the root of
    6623             :   // the child preserves3d context doesn't create a transform item.
    6624             :   // With this flags, we force the item not extending 3D context.
    6625             :   bool mNoExtendContext;
    6626             :   // This item is a separator between 3D rendering contexts, and
    6627             :   // mTransform have been presetted by the constructor.
    6628             :   bool mIsTransformSeparator;
    6629             :   // True if mTransformPreserves3D have been initialized.
    6630             :   bool mTransformPreserves3DInited;
    6631             :   // True if async animation of the transform is allowed.
    6632             :   bool mAllowAsyncAnimation;
    6633             : };
    6634             : 
    6635             : /* A display item that applies a perspective transformation to a single
    6636           0 :  * nsDisplayTransform child item. We keep this as a separate item since the
    6637             :  * perspective-origin is relative to an ancestor of the transformed frame, and
    6638             :  * APZ can scroll the child separately.
    6639             :  */
    6640           0 : class nsDisplayPerspective : public nsDisplayItem
    6641           0 : {
    6642           0 :   typedef mozilla::gfx::Point3D Point3D;
    6643             : 
    6644           0 : public:
    6645             :   NS_DISPLAY_DECL_NAME("nsDisplayPerspective", TYPE_PERSPECTIVE)
    6646             : 
    6647           0 :   nsDisplayPerspective(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    6648             :                        nsDisplayList* aList);
    6649             :   ~nsDisplayPerspective()
    6650           0 :   {
    6651             :   }
    6652             : 
    6653           0 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    6654             :                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override
    6655             :   {
    6656           0 :     return mList.HitTest(aBuilder, aRect, aState, aOutFrames);
    6657             :   }
    6658           0 : 
    6659           0 :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
    6660             :                            bool* aSnap) const override
    6661           0 :   {
    6662             :     return mList.GetBounds(aBuilder, aSnap);
    6663             :   }
    6664           0 : 
    6665             :   virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
    6666           0 :   {
    6667             :     mList.UpdateBounds(aBuilder);
    6668             :   }
    6669           0 : 
    6670             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6671             :                                          const nsDisplayItemGeometry* aGeometry,
    6672           0 :                                          nsRegion* aInvalidRegion) const override
    6673             :   {}
    6674           0 : 
    6675             :   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    6676             :                                    bool* aSnap) const override
    6677             :   {
    6678             :     return mList.GetOpaqueRegion(aBuilder, aSnap);
    6679             :   }
    6680             : 
    6681             :   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override
    6682             :   {
    6683             :     return mList.IsUniform(aBuilder);
    6684             :   }
    6685             : 
    6686           0 :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    6687             :                                    LayerManager* aManager,
    6688           0 :                                    const ContainerLayerParameters& aParameters) override;
    6689             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    6690             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    6691           0 :                                const StackingContextHelper& aSc,
    6692             :                                mozilla::layers::WebRenderLayerManager* aManager,
    6693             :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    6694             : 
    6695             :   virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const override
    6696             :   {
    6697             :     if (!mList.GetChildren()->GetTop()) {
    6698           0 :       return false;
    6699             :     }
    6700             :     return mList.GetChildren()->GetTop()->ShouldBuildLayerEvenIfInvisible(aBuilder);
    6701           0 :   }
    6702           0 : 
    6703             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    6704             :                                              LayerManager* aManager,
    6705           0 :                                              const ContainerLayerParameters& aContainerParameters) override;
    6706             : 
    6707           0 :   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
    6708             :                                  nsRegion* aVisibleRegion) override
    6709             :   {
    6710           0 :     mList.RecomputeVisibility(aBuilder, aVisibleRegion);
    6711             :     return true;
    6712           0 :   }
    6713             : 
    6714             :   virtual nsDisplayList* GetSameCoordinateSystemChildren() const override
    6715           0 :   {
    6716             :     return mList.GetChildren();
    6717           0 :   }
    6718           0 : 
    6719           0 :   virtual RetainedDisplayList* GetChildren() const override
    6720             :   {
    6721           0 :     return mList.GetChildren();
    6722             :   }
    6723           0 : 
    6724             :   virtual void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) override
    6725             :   {
    6726             :     nsDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot);
    6727           0 :     mList.SetActiveScrolledRoot(aActiveScrolledRoot);
    6728           0 :   }
    6729           0 : 
    6730             :   virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
    6731           0 :   {
    6732             :     return mList.GetComponentAlphaBounds(aBuilder);
    6733           0 :   }
    6734             : 
    6735           0 :   virtual void
    6736           0 :   DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
    6737           0 :     if (mList.GetChildren()->GetTop()) {
    6738             :       static_cast<nsDisplayTransform*>(mList.GetChildren()->GetTop())->DoUpdateBoundsPreserves3D(aBuilder);
    6739           0 :     }
    6740             :   }
    6741           0 : 
    6742           0 :   virtual void Destroy(nsDisplayListBuilder* aBuilder) override
    6743           0 :   {
    6744             :     mList.GetChildren()->DeleteAll(aBuilder);
    6745             :     nsDisplayItem::Destroy(aBuilder);
    6746             :   }
    6747             : 
    6748             :   virtual void RemoveFrame(nsIFrame* aFrame) override
    6749             :   {
    6750             :     nsDisplayItem::RemoveFrame(aFrame);
    6751             :     mList.RemoveFrame(aFrame);
    6752             :   }
    6753             : 
    6754             : private:
    6755             :   nsDisplayWrapList mList;
    6756             : };
    6757             : 
    6758             : /**
    6759             :  * This class adds basic support for limiting the rendering (in the inline axis
    6760             :  * of the writing mode) to the part inside the specified edges.  It's a base
    6761             :  * class for the display item classes that do the actual work.
    6762             :  * The two members, mVisIStartEdge and mVisIEndEdge, are relative to the edges
    6763             :  * of the frame's scrollable overflow rectangle and are the amount to suppress
    6764             :  * on each side.
    6765             :  *
    6766             :  * Setting none, both or only one edge is allowed.
    6767             :  * The values must be non-negative.
    6768             :  * The default value for both edges is zero, which means everything is painted.
    6769             :  */
    6770             : class nsCharClipDisplayItem : public nsDisplayItem {
    6771             : public:
    6772             :   nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
    6773             :     : nsDisplayItem(aBuilder, aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
    6774             : 
    6775             :   explicit nsCharClipDisplayItem(nsIFrame* aFrame)
    6776             :     : nsDisplayItem(aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
    6777             : 
    6778             :   virtual void RestoreState() override
    6779             :   {
    6780             :     nsDisplayItem::RestoreState();
    6781             :     mIsFrameSelected.reset();
    6782             :   }
    6783             : 
    6784             :   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
    6785             : 
    6786             :   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
    6787             :                                          const nsDisplayItemGeometry* aGeometry,
    6788             :                                          nsRegion* aInvalidRegion) const override;
    6789             : 
    6790             :   struct ClipEdges {
    6791             :     ClipEdges(const nsDisplayItem& aItem,
    6792             :               nscoord aVisIStartEdge, nscoord aVisIEndEdge) {
    6793             :       nsRect r = aItem.Frame()->GetScrollableOverflowRect() +
    6794             :                  aItem.ToReferenceFrame();
    6795             :       if (aItem.Frame()->GetWritingMode().IsVertical()) {
    6796             :         mVisIStart = aVisIStartEdge > 0 ? r.y + aVisIStartEdge : nscoord_MIN;
    6797             :         mVisIEnd =
    6798             :           aVisIEndEdge > 0 ? std::max(r.YMost() - aVisIEndEdge, mVisIStart)
    6799             :                            : nscoord_MAX;
    6800             :       } else {
    6801             :         mVisIStart = aVisIStartEdge > 0 ? r.x + aVisIStartEdge : nscoord_MIN;
    6802             :         mVisIEnd =
    6803             :           aVisIEndEdge > 0 ? std::max(r.XMost() - aVisIEndEdge, mVisIStart)
    6804             :                            : nscoord_MAX;
    6805             :       }
    6806             :     }
    6807             :     void Intersect(nscoord* aVisIStart, nscoord* aVisISize) const {
    6808             :       nscoord end = *aVisIStart + *aVisISize;
    6809             :       *aVisIStart = std::max(*aVisIStart, mVisIStart);
    6810             :       *aVisISize = std::max(std::min(end, mVisIEnd) - *aVisIStart, 0);
    6811             :     }
    6812             :     nscoord mVisIStart;
    6813             :     nscoord mVisIEnd;
    6814             :   };
    6815             : 
    6816             :   ClipEdges Edges() const {
    6817             :     return ClipEdges(*this, mVisIStartEdge, mVisIEndEdge);
    6818             :   }
    6819             : 
    6820             :   static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
    6821             :     DisplayItemType t = aItem->GetType();
    6822             :     return (t == DisplayItemType::TYPE_TEXT ||
    6823             :             t == DisplayItemType::TYPE_SVG_CHAR_CLIP)
    6824             :       ? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr;
    6825             :   }
    6826             : 
    6827             :   // Lengths measured from the visual inline start and end sides
    6828             :   // (i.e. left and right respectively in horizontal writing modes,
    6829             :   // regardless of bidi directionality; top and bottom in vertical modes).
    6830             :   nscoord mVisIStartEdge;
    6831             :   nscoord mVisIEndEdge;
    6832           0 :   // Cached result of mFrame->IsSelected().  Only initialized when needed.
    6833             :   mutable mozilla::Maybe<bool> mIsFrameSelected;
    6834             : };
    6835             : 
    6836             : /**
    6837             :  * A display item that for webrender to handle SVG
    6838             :  */
    6839             : class nsDisplaySVGWrapper : public nsDisplayWrapList {
    6840             : public:
    6841             :   NS_DISPLAY_DECL_NAME("SVGWrapper", TYPE_SVG_WRAPPER)
    6842             : 
    6843             :   nsDisplaySVGWrapper(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
    6844             :                     nsDisplayList* aList);
    6845             : #ifdef NS_BUILD_REFCNT_LOGGING
    6846             :   virtual ~nsDisplaySVGWrapper();
    6847             : #endif
    6848             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
    6849             :                                              LayerManager* aManager,
    6850             :                                              const ContainerLayerParameters& aContainerParameters) override;
    6851             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
    6852             :                                    LayerManager* aManager,
    6853             :                                    const ContainerLayerParameters& aParameters) override;
    6854             :   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
    6855             : 
    6856             :   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
    6857             :                                mozilla::wr::IpcResourceUpdateQueue& aResources,
    6858             :                                const StackingContextHelper& aSc,
    6859             :                                mozilla::layers::WebRenderLayerManager* aManager,
    6860             :                                nsDisplayListBuilder* aDisplayListBuilder) override;
    6861             : };
    6862             : 
    6863             : namespace mozilla {
    6864             : 
    6865             : class PaintTelemetry
    6866             : {
    6867             :  public:
    6868             :   enum class Metric {
    6869             :     DisplayList,
    6870             :     Layerization,
    6871             :     Rasterization,
    6872             :     COUNT,
    6873             :   };
    6874             : 
    6875             :   class AutoRecord
    6876             :   {
    6877             :    public:
    6878             :     explicit AutoRecord(Metric aMetric);
    6879             :     ~AutoRecord();
    6880             : 
    6881             :     TimeStamp GetStart() const {
    6882             :       return mStart;
    6883             :     }
    6884             :    private:
    6885             :     Metric mMetric;
    6886             :     mozilla::TimeStamp mStart;
    6887             :   };
    6888             : 
    6889             :   class AutoRecordPaint
    6890             :   {
    6891             :    public:
    6892             :     AutoRecordPaint();
    6893             :     ~AutoRecordPaint();
    6894             :    private:
    6895             :     mozilla::TimeStamp mStart;
    6896             :   };
    6897             : 
    6898             :  private:
    6899             :   static uint32_t sPaintLevel;
    6900             :   static uint32_t sMetricLevel;
    6901             :   static mozilla::EnumeratedArray<Metric, Metric::COUNT, double> sMetrics;
    6902             : };
    6903             : 
    6904             : } // namespace mozilla
    6905             : 
    6906             : #endif /*NSDISPLAYLIST_H_*/

Generated by: LCOV version 1.13-14-ga5dd952