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 #ifndef DISPLAYITEMCLIPCHAIN_H_
8 #define DISPLAYITEMCLIPCHAIN_H_
9 
10 #include "mozilla/Assertions.h"
11 #include "DisplayItemClip.h"
12 #include "nsString.h"
13 
14 class nsIScrollableFrame;
15 
16 namespace mozilla {
17 
18 struct ActiveScrolledRoot;
19 
20 /**
21  * A DisplayItemClipChain is a linked list of DisplayItemClips where each clip
22  * is associated with an active scrolled root that describes what the clip
23  * moves with.
24  * We use a chain instead of just one intersected clip due to async scrolling:
25  * A clip that moves along with a display item can be fused to the item's
26  * contents when drawing the layer contents, but all other clips in the chain
27  * need to be kept separate so that they can be applied at composition time,
28  * after any async scroll offsets have been applied.
29  * The clip chain is created during display list construction by the builder's
30  * DisplayListClipState.
31  * The clip chain order is determined by the active scrolled root order.
32  * For every DisplayItemClipChain object |clipChain|, the following holds:
33  * !clipChain->mParent ||
34  * ActiveScrolledRoot::IsAncestor(clipChain->mParent->mASR, clipChain->mASR).
35  * The clip chain can skip over active scrolled roots. That just means that
36  * there is no clip that moves with the skipped ASR in this chain.
37  */
38 struct DisplayItemClipChain {
39   /**
40    * Get the display item clip in this chain that moves with aASR, or nullptr
41    * if no such clip exists. aClipChain can be null.
42    */
43   static const DisplayItemClip* ClipForASR(
44       const DisplayItemClipChain* aClipChain, const ActiveScrolledRoot* aASR);
45 
46   static bool Equal(const DisplayItemClipChain* aClip1,
47                     const DisplayItemClipChain* aClip2);
48   /**
49    * Hash function that returns the same value for any two clips A and B
50    * where Equal(A, B) is true.
51    */
52   static uint32_t Hash(const DisplayItemClipChain* aClip);
53 
54   static nsCString ToString(const DisplayItemClipChain* aClipChain);
55 
56   bool HasRoundedCorners() const;
57 
AddRefDisplayItemClipChain58   void AddRef() { mRefCount++; }
ReleaseDisplayItemClipChain59   void Release() {
60     MOZ_ASSERT(mRefCount > 0);
61     mRefCount--;
62   }
63 
DisplayItemClipChainDisplayItemClipChain64   DisplayItemClipChain(const DisplayItemClip& aClip,
65                        const ActiveScrolledRoot* aASR,
66                        const DisplayItemClipChain* aParent)
67       : mClip(aClip),
68         mASR(aASR),
69         mParent(aParent)
70 #ifdef DEBUG
71         ,
72         mOnStack(true)
73 #endif
74   {
75   }
76 
DisplayItemClipChainDisplayItemClipChain77   DisplayItemClipChain()
78 #ifdef DEBUG
79       : mOnStack(true)
80 #endif
81   {
82   }
83 
84   DisplayItemClip mClip;
85   const ActiveScrolledRoot* mASR;
86   RefPtr<const DisplayItemClipChain> mParent;
87   uint32_t mRefCount = 0;
88 #ifdef DEBUG
89   bool mOnStack;
90 #endif
91 };
92 
93 struct DisplayItemClipChainHasher {
94   typedef const DisplayItemClipChain* Key;
95 
operatorDisplayItemClipChainHasher96   std::size_t operator()(const Key& aKey) const {
97     return DisplayItemClipChain::Hash(aKey);
98   }
99 };
100 
101 struct DisplayItemClipChainEqualer {
102   typedef const DisplayItemClipChain* Key;
103 
operatorDisplayItemClipChainEqualer104   bool operator()(const Key& lhs, const Key& rhs) const {
105     return DisplayItemClipChain::Equal(lhs, rhs);
106   }
107 };
108 
109 }  // namespace mozilla
110 
111 #endif /* DISPLAYITEMCLIPCHAIN_H_ */
112