2017-10-27 20:33:53 +03:00
|
|
|
/* -*- 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
|
2017-01-27 14:57:44 +03:00
|
|
|
* 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"
|
|
|
|
|
2018-02-13 20:08:42 +03:00
|
|
|
#include "nsDisplayList.h"
|
|
|
|
|
2017-01-27 14:57:44 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-01-09 20:31:58 +03:00
|
|
|
bool ret = aClip1->mASR == aClip2->mASR &&
|
2017-01-27 14:57:44 +03:00
|
|
|
aClip1->mClip == aClip2->mClip &&
|
|
|
|
Equal(aClip1->mParent, aClip2->mParent);
|
2018-01-09 20:31:58 +03:00
|
|
|
// 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;
|
2017-01-27 14:57:44 +03:00
|
|
|
}
|
|
|
|
|
2018-01-06 17:52:58 +03:00
|
|
|
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();
|
2018-01-09 20:31:58 +03:00
|
|
|
// 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);
|
|
|
|
}
|
2018-01-06 17:52:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2017-01-27 14:57:44 +03:00
|
|
|
/* static */ nsCString
|
|
|
|
DisplayItemClipChain::ToString(const DisplayItemClipChain* aClipChain)
|
|
|
|
{
|
|
|
|
nsAutoCString str;
|
|
|
|
for (auto* sc = aClipChain; sc; sc = sc->mParent) {
|
|
|
|
if (sc->mASR) {
|
2018-01-06 17:52:57 +03:00
|
|
|
str.AppendPrintf("0x%p <%s> [0x%p]", sc, sc->mClip.ToString().get(), sc->mASR->mScrollableFrame);
|
2017-01-27 14:57:44 +03:00
|
|
|
} else {
|
2018-01-06 17:52:57 +03:00
|
|
|
str.AppendPrintf("0x%p <%s> [root asr]", sc, sc->mClip.ToString().get());
|
2017-01-27 14:57:44 +03:00
|
|
|
}
|
|
|
|
if (sc->mParent) {
|
2017-09-04 08:14:11 +03:00
|
|
|
str.AppendLiteral(", ");
|
2017-01-27 14:57:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
DisplayItemClipChain::HasRoundedCorners() const
|
|
|
|
{
|
|
|
|
return mClip.GetRoundedRectCount() > 0 || (mParent && mParent->HasRoundedCorners());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mozilla
|