Bug 1578295 - Use cbindgen for counters. r=mats

Differential Revision: https://phabricator.services.mozilla.com/D44403

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-09-02 23:11:26 +00:00
Родитель 9f378c9fc1
Коммит d5bc03b6f0
11 изменённых файлов: 86 добавлений и 235 удалений

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

@ -188,9 +188,31 @@ void nsCounterList::RecalcAll() {
}
}
static bool AddCounterChangeNode(nsCounterManager& aManager, nsIFrame* aFrame,
int32_t aIndex,
const nsStyleContent::CounterPair& aPair,
nsCounterNode::Type aType) {
auto* node = new nsCounterChangeNode(aFrame, aType, aPair.value, aIndex);
nsCounterList* counterList = aManager.CounterListFor(aPair.name.AsAtom());
counterList->Insert(node);
if (!counterList->IsLast(node)) {
// Tell the caller it's responsible for recalculating the entire
// list.
counterList->SetDirty();
return true;
}
// Don't call Calc() if the list is already dirty -- it'll be recalculated
// anyway, and trying to calculate with a dirty list doesn't work.
if (MOZ_LIKELY(!counterList->IsDirty())) {
node->Calc(counterList);
}
return false;
}
static bool HasCounters(const nsStyleContent& aStyle) {
return aStyle.CounterIncrementCount() || aStyle.CounterResetCount() ||
aStyle.CounterSetCount();
return !aStyle.mCounterIncrement.IsEmpty() ||
!aStyle.mCounterReset.IsEmpty() || !aStyle.mCounterSet.IsEmpty();
}
bool nsCounterManager::AddCounterChanges(nsIFrame* aFrame) {
@ -217,56 +239,44 @@ bool nsCounterManager::AddCounterChanges(nsIFrame* aFrame) {
bool dirty = false;
// Add in order, resets first, so all the comparisons will be optimized
// for addition at the end of the list.
for (int32_t i : IntegerRange(styleContent->CounterResetCount())) {
dirty |= AddCounterChangeNode(aFrame, i, styleContent->CounterResetAt(i),
nsCounterChangeNode::RESET);
{
int32_t i = 0;
for (const auto& pair : styleContent->mCounterReset.AsSpan()) {
dirty |= AddCounterChangeNode(*this, aFrame, i++, pair,
nsCounterChangeNode::RESET);
}
}
bool hasListItemIncrement = false;
for (int32_t i : IntegerRange(styleContent->CounterIncrementCount())) {
const nsStyleCounterData& increment = styleContent->CounterIncrementAt(i);
hasListItemIncrement |= increment.mCounter == nsGkAtoms::list_item;
dirty |= AddCounterChangeNode(aFrame, i, increment,
nsCounterChangeNode::INCREMENT);
{
int32_t i = 0;
for (const auto& pair : styleContent->mCounterIncrement.AsSpan()) {
hasListItemIncrement |= pair.name.AsAtom() == nsGkAtoms::list_item;
dirty |= AddCounterChangeNode(*this, aFrame, i++, pair,
nsCounterChangeNode::INCREMENT);
}
}
if (requiresListItemIncrement && !hasListItemIncrement) {
bool reversed =
aFrame->StyleList()->mMozListReversed == StyleMozListReversed::True;
nsStyleCounterData listItemIncrement{nsGkAtoms::list_item,
reversed ? -1 : 1};
dirty |=
AddCounterChangeNode(aFrame, styleContent->CounterIncrementCount() + 1,
listItemIncrement, nsCounterChangeNode::INCREMENT);
RefPtr<nsAtom> atom = nsGkAtoms::list_item;
auto listItemIncrement = nsStyleContent::CounterPair{
{StyleAtom(atom.forget())}, reversed ? -1 : 1};
dirty |= AddCounterChangeNode(
*this, aFrame, styleContent->mCounterIncrement.Length(),
listItemIncrement, nsCounterChangeNode::INCREMENT);
}
for (int32_t i : IntegerRange(styleContent->CounterSetCount())) {
dirty |= AddCounterChangeNode(aFrame, i, styleContent->CounterSetAt(i),
nsCounterChangeNode::SET);
{
int32_t i = 0;
for (const auto& pair : styleContent->mCounterSet.AsSpan()) {
dirty |= AddCounterChangeNode(*this, aFrame, i++, pair,
nsCounterChangeNode::SET);
}
}
return dirty;
}
bool nsCounterManager::AddCounterChangeNode(
nsIFrame* aFrame, int32_t aIndex, const nsStyleCounterData& aCounterData,
nsCounterNode::Type aType) {
nsCounterChangeNode* node =
new nsCounterChangeNode(aFrame, aType, aCounterData.mValue, aIndex);
nsCounterList* counterList = CounterListFor(aCounterData.mCounter);
counterList->Insert(node);
if (!counterList->IsLast(node)) {
// Tell the caller it's responsible for recalculating the entire
// list.
counterList->SetDirty();
return true;
}
// Don't call Calc() if the list is already dirty -- it'll be recalculated
// anyway, and trying to calculate with a dirty list doesn't work.
if (MOZ_LIKELY(!counterList->IsDirty())) {
node->Calc(counterList);
}
return false;
}
nsCounterList* nsCounterManager::CounterListFor(nsAtom* aCounterName) {
MOZ_ASSERT(aCounterName);
return mNames.LookupForAdd(aCounterName).OrInsert([]() {

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

@ -263,11 +263,6 @@ class nsCounterManager {
}
private:
// for |AddCounterChanges| only
bool AddCounterChangeNode(nsIFrame* aFrame, int32_t aIndex,
const nsStyleCounterData& aCounterData,
nsCounterNode::Type aType);
nsClassHashtable<nsRefPtrHashKey<nsAtom>, nsCounterList> mNames;
};

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

@ -1262,57 +1262,6 @@ void Gecko_CopyStyleContentsFrom(nsStyleContent* aContent,
}
}
void Gecko_ClearAndResizeCounterIncrements(nsStyleContent* aContent,
uint32_t aHowMany) {
aContent->AllocateCounterIncrements(aHowMany);
}
void Gecko_CopyCounterIncrementsFrom(nsStyleContent* aContent,
const nsStyleContent* aOther) {
uint32_t count = aOther->CounterIncrementCount();
aContent->AllocateCounterIncrements(count);
for (uint32_t i = 0; i < count; ++i) {
const nsStyleCounterData& data = aOther->CounterIncrementAt(i);
aContent->SetCounterIncrementAt(i, data.mCounter, data.mValue);
}
}
void Gecko_ClearAndResizeCounterResets(nsStyleContent* aContent,
uint32_t aHowMany) {
aContent->AllocateCounterResets(aHowMany);
}
void Gecko_CopyCounterResetsFrom(nsStyleContent* aContent,
const nsStyleContent* aOther) {
uint32_t count = aOther->CounterResetCount();
aContent->AllocateCounterResets(count);
for (uint32_t i = 0; i < count; ++i) {
const nsStyleCounterData& data = aOther->CounterResetAt(i);
aContent->SetCounterResetAt(i, data.mCounter, data.mValue);
}
}
void Gecko_ClearAndResizeCounterSets(nsStyleContent* aContent,
uint32_t aHowMany) {
aContent->AllocateCounterSets(aHowMany);
}
void Gecko_CopyCounterSetsFrom(nsStyleContent* aContent,
const nsStyleContent* aOther) {
uint32_t count = aOther->CounterSetCount();
aContent->AllocateCounterSets(count);
for (uint32_t i = 0; i < count; ++i) {
const nsStyleCounterData& data = aOther->CounterSetAt(i);
aContent->SetCounterSetAt(i, data.mCounter, data.mValue);
}
}
void Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
nsStyleImageLayers::LayerType aLayerType) {
size_t oldLength = aLayers->mLayers.Length();

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

@ -423,28 +423,9 @@ void Gecko_ResizeAtomArray(nsTArray<RefPtr<nsAtom>>* array, uint32_t length);
// we'd leak the images, strings, and whatnot.
void Gecko_ClearAndResizeStyleContents(nsStyleContent* content,
uint32_t how_many);
void Gecko_ClearAndResizeCounterIncrements(nsStyleContent* content,
uint32_t how_many);
void Gecko_ClearAndResizeCounterResets(nsStyleContent* content,
uint32_t how_many);
void Gecko_ClearAndResizeCounterSets(nsStyleContent* content,
uint32_t how_many);
void Gecko_CopyStyleContentsFrom(nsStyleContent* content,
const nsStyleContent* other);
void Gecko_CopyCounterResetsFrom(nsStyleContent* content,
const nsStyleContent* other);
void Gecko_CopyCounterSetsFrom(nsStyleContent* content,
const nsStyleContent* other);
void Gecko_CopyCounterIncrementsFrom(nsStyleContent* content,
const nsStyleContent* other);
void Gecko_EnsureImageLayersLength(nsStyleImageLayers* layers, size_t len,
nsStyleImageLayers::LayerType layer_type);

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

@ -524,6 +524,8 @@ cbindgen-types = [
{ gecko = "StyleVariantAlternatesList", servo = "values::specified::font::VariantAlternatesList" },
{ gecko = "StyleSVGPaintOrder", servo = "values::specified::svg::SVGPaintOrder" },
{ gecko = "StyleClipRectOrAuto", servo = "values::computed::ClipRectOrAuto" },
{ gecko = "StyleCounterSetOrReset", servo = "values::computed::CounterSetOrReset" },
{ gecko = "StyleCounterIncrement", servo = "values::computed::CounterIncrement" },
]
mapped-generic-types = [

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

@ -3275,9 +3275,9 @@ void nsStyleContent::TriggerImageLoads(Document& aDocument,
nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
: mContents(aSource.mContents),
mIncrements(aSource.mIncrements),
mResets(aSource.mResets),
mSets(aSource.mSets) {
mCounterIncrement(aSource.mCounterIncrement),
mCounterReset(aSource.mCounterReset),
mCounterSet(aSource.mCounterSet) {
MOZ_COUNT_CTOR(nsStyleContent);
}
@ -3286,8 +3286,10 @@ nsChangeHint nsStyleContent::CalcDifference(
// Unfortunately we need to reframe even if the content lengths are the same;
// a simple reflow will not pick up different text or different image URLs,
// since we set all that up in the CSSFrameConstructor
if (mContents != aNewData.mContents || mIncrements != aNewData.mIncrements ||
mResets != aNewData.mResets || mSets != aNewData.mSets) {
if (mContents != aNewData.mContents ||
mCounterIncrement != aNewData.mCounterIncrement ||
mCounterReset != aNewData.mCounterReset ||
mCounterSet != aNewData.mCounterSet) {
return nsChangeHint_ReconstructFrame;
}

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

@ -2019,6 +2019,8 @@ struct nsStyleCounterData {
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent {
using CounterPair = mozilla::StyleGenericCounterPair<int32_t>;
explicit nsStyleContent(const mozilla::dom::Document&);
nsStyleContent(const nsStyleContent& aContent);
~nsStyleContent();
@ -2045,57 +2047,13 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent {
mContents.SetLength(aCount);
}
uint32_t CounterIncrementCount() const { return mIncrements.Length(); }
const nsStyleCounterData& CounterIncrementAt(uint32_t aIndex) const {
return mIncrements[aIndex];
}
void AllocateCounterIncrements(uint32_t aCount) {
mIncrements.Clear();
mIncrements.SetLength(aCount);
}
void SetCounterIncrementAt(uint32_t aIndex, nsAtom* aCounter,
int32_t aIncrement) {
mIncrements[aIndex].mCounter = aCounter;
mIncrements[aIndex].mValue = aIncrement;
}
uint32_t CounterResetCount() const { return mResets.Length(); }
const nsStyleCounterData& CounterResetAt(uint32_t aIndex) const {
return mResets[aIndex];
}
void AllocateCounterResets(uint32_t aCount) {
mResets.Clear();
mResets.SetLength(aCount);
}
void SetCounterResetAt(uint32_t aIndex, nsAtom* aCounter, int32_t aValue) {
mResets[aIndex].mCounter = aCounter;
mResets[aIndex].mValue = aValue;
}
uint32_t CounterSetCount() const { return mSets.Length(); }
const nsStyleCounterData& CounterSetAt(uint32_t aIndex) const {
return mSets[aIndex];
}
void AllocateCounterSets(uint32_t aCount) {
mSets.Clear();
mSets.SetLength(aCount);
}
void SetCounterSetAt(uint32_t aIndex, nsAtom* aCounter, int32_t aValue) {
mSets[aIndex].mCounter = aCounter;
mSets[aIndex].mValue = aValue;
}
protected:
nsTArray<nsStyleContentData> mContents;
nsTArray<nsStyleCounterData> mIncrements;
nsTArray<nsStyleCounterData> mResets;
nsTArray<nsStyleCounterData> mSets;
public:
mozilla::StyleCounterIncrement mCounterIncrement;
mozilla::StyleCounterSetOrReset mCounterReset;
mozilla::StyleCounterSetOrReset mCounterSet;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {

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

@ -2579,8 +2579,7 @@ clip-path
${impl_simple('column_rule_style', 'mColumnRuleStyle')}
</%self:impl_trait>
<%self:impl_trait style_struct_name="Counters"
skip_longhands="content counter-increment counter-reset counter-set">
<%self:impl_trait style_struct_name="Counters" skip_longhands="content">
pub fn ineffective_content_property(&self) -> bool {
self.gecko.mContents.is_empty()
}
@ -2811,51 +2810,6 @@ clip-path
}).collect::<Vec<_>>().into_boxed_slice()
)
}
% for counter_property in ["Increment", "Reset", "Set"]:
pub fn set_counter_${counter_property.lower()}(
&mut self,
v: longhands::counter_${counter_property.lower()}::computed_value::T
) {
unsafe {
bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut *self.gecko, v.len() as u32);
for (i, pair) in v.0.into_vec().into_iter().enumerate() {
self.gecko.m${counter_property}s[i].mCounter.set_move(
RefPtr::from_addrefed(pair.name.0.into_addrefed())
);
self.gecko.m${counter_property}s[i].mValue = pair.value;
}
}
}
pub fn copy_counter_${counter_property.lower()}_from(&mut self, other: &Self) {
unsafe {
bindings::Gecko_CopyCounter${counter_property}sFrom(&mut *self.gecko, &*other.gecko)
}
}
pub fn reset_counter_${counter_property.lower()}(&mut self, other: &Self) {
self.copy_counter_${counter_property.lower()}_from(other)
}
pub fn clone_counter_${counter_property.lower()}(
&self
) -> longhands::counter_${counter_property.lower()}::computed_value::T {
use crate::values::generics::counters::CounterPair;
use crate::values::CustomIdent;
longhands::counter_${counter_property.lower()}::computed_value::T::new(
self.gecko.m${counter_property}s.iter().map(|ref gecko_counter| {
CounterPair {
name: CustomIdent(unsafe {
Atom::from_raw(gecko_counter.mCounter.mRawPtr)
}),
value: gecko_counter.mValue,
}
}).collect()
)
}
% endfor
</%self:impl_trait>
<%self:impl_trait style_struct_name="UI" skip_longhands="-moz-force-broken-image-icon">

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

@ -25,12 +25,14 @@ use std::ops::Deref;
ToResolvedValue,
ToShmem,
)]
pub struct CounterPair<Integer> {
#[repr(C)]
pub struct GenericCounterPair<Integer> {
/// The name of the counter.
pub name: CustomIdent,
/// The value of the counter / increment / etc.
pub value: Integer,
}
pub use self::GenericCounterPair as CounterPair;
/// A generic value for the `counter-increment` property.
#[derive(
@ -45,13 +47,15 @@ pub struct CounterPair<Integer> {
ToResolvedValue,
ToShmem,
)]
pub struct CounterIncrement<I>(pub Counters<I>);
#[repr(transparent)]
pub struct GenericCounterIncrement<I>(pub GenericCounters<I>);
pub use self::GenericCounterIncrement as CounterIncrement;
impl<I> CounterIncrement<I> {
/// Returns a new value for `counter-increment`.
#[inline]
pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterIncrement(Counters(counters.into_boxed_slice()))
CounterIncrement(Counters(counters.into()))
}
}
@ -77,13 +81,15 @@ impl<I> Deref for CounterIncrement<I> {
ToResolvedValue,
ToShmem,
)]
pub struct CounterSetOrReset<I>(pub Counters<I>);
#[repr(transparent)]
pub struct GenericCounterSetOrReset<I>(pub GenericCounters<I>);
pub use self::GenericCounterSetOrReset as CounterSetOrReset;
impl<I> CounterSetOrReset<I> {
/// Returns a new value for `counter-set` / `counter-reset`.
#[inline]
pub fn new(counters: Vec<CounterPair<I>>) -> Self {
CounterSetOrReset(Counters(counters.into_boxed_slice()))
CounterSetOrReset(Counters(counters.into()))
}
}
@ -111,17 +117,9 @@ impl<I> Deref for CounterSetOrReset<I> {
ToResolvedValue,
ToShmem,
)]
pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);
impl<I> Counters<I> {
/// Move out the Box into a vector. This could just return the Box<>, but
/// Vec<> is a bit more convenient because Box<[T]> doesn't implement
/// IntoIter: https://github.com/rust-lang/rust/issues/59878
#[inline]
pub fn into_vec(self) -> Vec<CounterPair<I>> {
self.0.into_vec()
}
}
#[repr(transparent)]
pub struct GenericCounters<I>(#[css(iterable, if_empty = "none")] crate::OwnedSlice<GenericCounterPair<I>>);
pub use self::GenericCounters as Counters;
#[cfg(feature = "servo")]
type CounterStyleType = ListStyleType;

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

@ -8,9 +8,9 @@
use crate::computed_values::list_style_type::T as ListStyleType;
use crate::parser::{Parse, ParserContext};
use crate::values::generics::counters as generics;
use crate::values::generics::counters::CounterIncrement as GenericCounterIncrement;
use crate::values::generics::counters::GenericCounterIncrement;
use crate::values::generics::counters::CounterPair;
use crate::values::generics::counters::CounterSetOrReset as GenericCounterSetOrReset;
use crate::values::generics::counters::GenericCounterSetOrReset;
#[cfg(feature = "gecko")]
use crate::values::generics::CounterStyle;
use crate::values::specified::url::SpecifiedImageUrl;

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

@ -174,6 +174,8 @@ include = [
"PaintOrder",
"SVGPaintOrder",
"ClipRectOrAuto",
"CounterSetOrReset",
"CounterIncrement",
]
item_types = ["enums", "structs", "typedefs", "functions", "constants"]
renaming_overrides_prefixing = true