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 DisplayItemClipChain* aNextClipChainToDestroy) 68 : mClip(aClip), 69 mASR(aASR), 70 mParent(aParent), 71 mNextClipChainToDestroy(aNextClipChainToDestroy) 72 #ifdef DEBUG 73 , 74 mOnStack(true) 75 #endif 76 { 77 } 78 DisplayItemClipChainDisplayItemClipChain79 DisplayItemClipChain() 80 : mASR(nullptr), 81 mNextClipChainToDestroy(nullptr) 82 #ifdef DEBUG 83 , 84 mOnStack(true) 85 #endif 86 { 87 } 88 89 DisplayItemClip mClip; 90 const ActiveScrolledRoot* mASR; 91 RefPtr<const DisplayItemClipChain> mParent; 92 uint32_t mRefCount = 0; 93 DisplayItemClipChain* mNextClipChainToDestroy; 94 #ifdef DEBUG 95 bool mOnStack; 96 #endif 97 }; 98 99 struct DisplayItemClipChainHasher { 100 typedef const DisplayItemClipChain* Key; 101 operatorDisplayItemClipChainHasher102 std::size_t operator()(const Key& aKey) const { 103 return DisplayItemClipChain::Hash(aKey); 104 } 105 }; 106 107 struct DisplayItemClipChainEqualer { 108 typedef const DisplayItemClipChain* Key; 109 operatorDisplayItemClipChainEqualer110 bool operator()(const Key& lhs, const Key& rhs) const { 111 return DisplayItemClipChain::Equal(lhs, rhs); 112 } 113 }; 114 115 } // namespace mozilla 116 117 #endif /* DISPLAYITEMCLIPCHAIN_H_ */ 118