зеркало из https://github.com/mozilla/gecko-dev.git
88 строки
3.0 KiB
C++
88 строки
3.0 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "DisplayItemClipChain.h"
|
|
|
|
#include "nsDisplayList.h"
|
|
|
|
namespace mozilla {
|
|
|
|
/* static */ const DisplayItemClip* DisplayItemClipChain::ClipForASR(
|
|
const DisplayItemClipChain* aClipChain, const ActiveScrolledRoot* aASR) {
|
|
while (aClipChain &&
|
|
!ActiveScrolledRoot::IsAncestor(aClipChain->mASR, aASR)) {
|
|
aClipChain = aClipChain->mParent;
|
|
}
|
|
return (aClipChain && aClipChain->mASR == aASR) ? &aClipChain->mClip
|
|
: nullptr;
|
|
}
|
|
|
|
bool DisplayItemClipChain::Equal(const DisplayItemClipChain* aClip1,
|
|
const DisplayItemClipChain* aClip2) {
|
|
if (aClip1 == aClip2) {
|
|
return true;
|
|
}
|
|
|
|
if (!aClip1 || !aClip2) {
|
|
return false;
|
|
}
|
|
|
|
bool ret = aClip1->mASR == aClip2->mASR && aClip1->mClip == aClip2->mClip &&
|
|
Equal(aClip1->mParent, aClip2->mParent);
|
|
// Sanity check: if two clip chains are equal they must hash to the same
|
|
// thing too, or Bad Things (TM) will happen.
|
|
MOZ_ASSERT(!ret || (Hash(aClip1) == Hash(aClip2)));
|
|
return ret;
|
|
}
|
|
|
|
uint32_t DisplayItemClipChain::Hash(const DisplayItemClipChain* aClip) {
|
|
if (!aClip) {
|
|
return 0;
|
|
}
|
|
|
|
// We include the number of rounded rects in the hash but not their contents.
|
|
// This is to keep the hash fast, because most clips will not have rounded
|
|
// rects and including them will slow down the hash in the common case. Note
|
|
// that the ::Equal check still checks the rounded rect contents, so in case
|
|
// of hash collisions the clip chains can still be distinguished using that.
|
|
uint32_t hash = HashGeneric(aClip->mASR, aClip->mClip.GetRoundedRectCount());
|
|
if (aClip->mClip.HasClip()) {
|
|
const nsRect& rect = aClip->mClip.GetClipRect();
|
|
// empty rects are considered equal in DisplayItemClipChain::Equal, even
|
|
// though they may have different x and y coordinates. So make sure they
|
|
// hash to the same thing in those cases too.
|
|
if (!rect.IsEmpty()) {
|
|
hash = AddToHash(hash, rect.x, rect.y, rect.width, rect.height);
|
|
}
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
/* static */ nsCString DisplayItemClipChain::ToString(
|
|
const DisplayItemClipChain* aClipChain) {
|
|
nsAutoCString str;
|
|
for (auto* sc = aClipChain; sc; sc = sc->mParent) {
|
|
if (sc->mASR) {
|
|
str.AppendPrintf("0x%p <%s> [0x%p]", sc, sc->mClip.ToString().get(),
|
|
sc->mASR->mScrollableFrame);
|
|
} else {
|
|
str.AppendPrintf("0x%p <%s> [root asr]", sc, sc->mClip.ToString().get());
|
|
}
|
|
if (sc->mParent) {
|
|
str.AppendLiteral(", ");
|
|
}
|
|
}
|
|
return std::move(str);
|
|
}
|
|
|
|
bool DisplayItemClipChain::HasRoundedCorners() const {
|
|
return mClip.GetRoundedRectCount() > 0 ||
|
|
(mParent && mParent->HasRoundedCorners());
|
|
}
|
|
|
|
} // namespace mozilla
|