DisplayItemClipChain.cpp (3097B)
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 #include "DisplayItemClipChain.h" 8 9 #include "nsDisplayList.h" 10 11 namespace mozilla { 12 13 /* static */ const DisplayItemClip* DisplayItemClipChain::ClipForASR( 14 const DisplayItemClipChain* aClipChain, const ActiveScrolledRoot* aASR) { 15 while (aClipChain && 16 !ActiveScrolledRoot::IsAncestor(aClipChain->mASR, aASR)) { 17 aClipChain = aClipChain->mParent; 18 } 19 return (aClipChain && aClipChain->mASR == aASR) ? &aClipChain->mClip 20 : nullptr; 21 } 22 23 bool DisplayItemClipChain::Equal(const DisplayItemClipChain* aClip1, 24 const DisplayItemClipChain* aClip2) { 25 if (aClip1 == aClip2) { 26 return true; 27 } 28 29 if (!aClip1 || !aClip2) { 30 return false; 31 } 32 33 bool ret = aClip1->mASR == aClip2->mASR && aClip1->mClip == aClip2->mClip && 34 Equal(aClip1->mParent, aClip2->mParent); 35 // Sanity check: if two clip chains are equal they must hash to the same 36 // thing too, or Bad Things (TM) will happen. 37 MOZ_ASSERT(!ret || (Hash(aClip1) == Hash(aClip2))); 38 return ret; 39 } 40 41 uint32_t DisplayItemClipChain::Hash(const DisplayItemClipChain* aClip) { 42 if (!aClip) { 43 return 0; 44 } 45 46 // We include the number of rounded rects in the hash but not their contents. 47 // This is to keep the hash fast, because most clips will not have rounded 48 // rects and including them will slow down the hash in the common case. Note 49 // that the ::Equal check still checks the rounded rect contents, so in case 50 // of hash collisions the clip chains can still be distinguished using that. 51 uint32_t hash = HashGeneric(aClip->mASR, aClip->mClip.GetRoundedRectCount()); 52 if (aClip->mClip.HasClip()) { 53 const nsRect& rect = aClip->mClip.GetClipRect(); 54 // empty rects are considered equal in DisplayItemClipChain::Equal, even 55 // though they may have different x and y coordinates. So make sure they 56 // hash to the same thing in those cases too. 57 if (!rect.IsEmpty()) { 58 hash = AddToHash(hash, rect.x, rect.y, rect.width, rect.height); 59 } 60 } 61 62 return hash; 63 } 64 65 /* static */ 66 nsCString DisplayItemClipChain::ToString( 67 const DisplayItemClipChain* aClipChain) { 68 nsAutoCString str; 69 for (auto* sc = aClipChain; sc; sc = sc->mParent) { 70 if (sc->mASR) { 71 str.AppendPrintf("0x%p <%s> %s", sc, sc->mClip.ToString().get(), 72 ActiveScrolledRoot::ToString(sc->mASR).get()); 73 } else { 74 str.AppendPrintf("0x%p <%s> [root asr]", sc, sc->mClip.ToString().get()); 75 } 76 if (sc->mParent) { 77 str.AppendLiteral(", "); 78 } 79 } 80 return std::move(str); 81 } 82 83 bool DisplayItemClipChain::HasRoundedCorners() const { 84 return mClip.GetRoundedRectCount() > 0 || 85 (mParent && mParent->HasRoundedCorners()); 86 } 87 88 } // namespace mozilla