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