Bug 931668 - Part 18: Add a function to swap style structs between style contexts. r=dbaron

--HG--
extra : rebase_source : 4d32ed1f140db975b2fffe76ac6bd793287c916c
This commit is contained in:
Cameron McCormack 2014-09-05 13:48:46 +10:00
Родитель 7130a6b300
Коммит baa35dd12a
2 изменённых файлов: 69 добавлений и 0 удалений

Просмотреть файл

@ -1039,3 +1039,52 @@ nsStyleContext::HasSameCachedStyleData(nsStyleContext* aOther,
{
return GetCachedStyleData(aSID) == aOther->GetCachedStyleData(aSID);
}
void
nsStyleContext::SwapStyleData(nsStyleContext* aNewContext, uint32_t aStructs)
{
static_assert(nsStyleStructID_Length <= 32, "aStructs is not big enough");
for (nsStyleStructID i = nsStyleStructID_Inherited_Start;
i < nsStyleStructID_Inherited_Start + nsStyleStructID_Inherited_Count;
i = nsStyleStructID(i + 1)) {
uint32_t bit = nsCachedStyleData::GetBitForSID(i);
if (!(aStructs & bit)) {
continue;
}
void*& thisData = mCachedInheritedData.mStyleStructs[i];
void*& otherData = aNewContext->mCachedInheritedData.mStyleStructs[i];
if (mBits & bit) {
if (thisData == otherData) {
thisData = nullptr;
}
} else if (!(aNewContext->mBits & bit) && thisData && otherData) {
std::swap(thisData, otherData);
}
}
for (nsStyleStructID i = nsStyleStructID_Reset_Start;
i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count;
i = nsStyleStructID(i + 1)) {
uint32_t bit = nsCachedStyleData::GetBitForSID(i);
if (!(aStructs & bit)) {
continue;
}
if (!mCachedResetData) {
mCachedResetData = new (mRuleNode->PresContext()) nsResetStyleData;
}
if (!aNewContext->mCachedResetData) {
aNewContext->mCachedResetData =
new (mRuleNode->PresContext()) nsResetStyleData;
}
void*& thisData = mCachedResetData->mStyleStructs[i];
void*& otherData = aNewContext->mCachedResetData->mStyleStructs[i];
if (mBits & bit) {
if (thisData == otherData) {
thisData = nullptr;
}
} else if (!(aNewContext->mBits & bit) && thisData && otherData) {
std::swap(thisData, otherData);
}
}
}

Просмотреть файл

@ -360,6 +360,26 @@ public:
*/
void MoveTo(nsStyleContext* aNewParent);
/**
* Swaps owned style struct pointers between this and aNewContext, on
* the assumption that aNewContext is the new style context for a frame
* and this is the old one. aStructs indicates which structs to consider
* swapping; only those which are owned in both this and aNewContext
* will be swapped.
*
* Additionally, if there are identical struct pointers for one of the
* structs indicated by aStructs, and it is not an owned struct on this,
* then the cached struct slot on this will be set to null. If the struct
* has been swapped on an ancestor, this style context (being the old one)
* will be left caching the struct pointer on the new ancestor, despite
* inheriting from the old ancestor. This is not normally a problem, as
* this style context will usually be destroyed by being released at the
* end of ElementRestyler::Restyle; but for style contexts held on to outside
* of the frame, we need to clear out the cached pointer so that if we need
* it again we'll re-fetch it from the new ancestor.
*/
void SwapStyleData(nsStyleContext* aNewContext, uint32_t aStructs);
#ifdef DEBUG
void List(FILE* out, int32_t aIndent);
static void AssertStyleStructMaxDifferenceValid();