We call NS_FRAME_SET_TRUNCATION (via nsReflowStatus::UpdateTruncated) in the end
of every frame's Reflow() to update nsReflowStatus::mTruncated bit. In the
following patches, I'm going to rewrite all the callers of IsTruncated(), and
ultimately remove the mTruncated bit.
In this patch, I rewrite the callsite in ReflowCellFrame() by moving
nsReflowStatus::UpdateTruncated logic [1] into it. Note that we use an assertion
in ReflowCellFrame to make sure nsTableRowFrame and nsTableCellFrame have the
same writing-mode.
The only test covering the code path is `layout/reftests/bugs/409084-1a.html`.
[1] https://searchfox.org/mozilla-central/rev/2946e9b450cb35afaf8dad927a8d187975dcd74d/layout/generic/nsIFrame.cpp#256-258
Differential Revision: https://phabricator.services.mozilla.com/D151459
This patch refactors how clip chains are internally represented and used
during scene and frame building. The intent is to make clip processing
during frame building more efficient and consistent. Additionally, this
work enables follow ups to cache the result of clip-chain builds between
frame and scene builds.
These changes will significantly reduce the cost of the visibility pass
for the common case when not much content has changed. In this patch,
the public API for clipping remains (mostly) the same, in order to allow
landing and stabilising this work without major changes to Gecko. However,
a longer term goal is to make the public WR clip API more closely match
the internal representation, to reduce work done during scene building.
Clips on a primitive can be categorized into two buckets. The first are
local clips that are specific to the primitive and move with it. These
could essentially be considered part of the definition of the primitive
itself. The second are a hierarchy of clips that apply to one or more
items, and may move independently of the primitive(s) they clip. These
clips are things like scroll regions, stacking context clips, iframe
clip regions etc. On (real world) pages, the clip hierarchy is typically
quite shallow, with a small number of clips that are shared by a large
number of primitives.
Finding clips that are shared between primitives is both required (for
things such as determining which picture cache slice a primitive can
be assigned to, while applying the shared clips during composition), and
also a potential optimization (processing shared clips only once and
caching this clip state similar primitives).
The public clip-chain API has two complexities that make the above
difficult and time consuming for WR to determine. It was possible to
express a clipping hierarchy both via the legacy clip parenting path
(via `ClipId` definitions) and also via clip-chains (the `parent`
field of a `ClipChain`). Second, clip-chains themselves can define
an arbitrary number and ordering of clips. Clips can also implicitly
apply to primitives via parent stacking contexts and iframes, but must
sometimes be removed (when an intermediate surface is created) for
performance reasons.
The new internal representation provided by this patch introduces a
`ClipTree` structure which is built during scene building by accumulating
the set of clips that apply to a primitive from all explicit and implicit
sources, and grafting this on to the existing clip-tree structure.
This provides WR a simple way to determine which clips are shared between
primitive (by checking ancestry) and reduces the size of the internal
representation (by sharing clips where possible rather than duplicating).
Interning is still used to identify parts of the clip-tree that define
the same clipping state.
Specific changes in this patch:
* Remove legacy `ClipId` style parenting support (in conjunction with
previous patches)
* Remove the public API ability to specify the clip on a primitive via
`ClipId` (it must now be a clip-chain)
* Remove `combined_local_clip_rect` from `PrimitiveInstance`, reducing
the size of the structure significantly
* Introduce `ClipTree` used during frame building, which is created by
`ClipTreeBuilder` during scene building
* Separate out per-primitive clip concept (`ClipTreeLeaf`) from clipping
hierarchy (`ClipTreeNode`). In future, more elements will be moved to
the `ClipTreeLeaf` and the state of each `ClipTreeNode` will be cached)
* Simplify the logic to disable / remove clips during frame building that
are applied by parent surface(s)
* Port hit-testing to be based on `ClipTree` which is simpler, faster and
also resolves some edge case correctness bugs
* Use a simpler and faster method to find shared clips during picture
cache slice assignment of primitives
* Update wrench to use the public clip-chain API definition changes
This patch already introduces some real-world optimizations (for example,
`displaylist_mutate` becomes 6% faster overall), but mostly sets things
up for follow up patches to be able to cache clip-state between frames,
which should result in much larger wins.
Differential Revision: https://phabricator.services.mozilla.com/D151987
mWebglValid gets initialized to false, but it will never get reset to true until the next
frame, causing us to render into Skia the first frame rather than accelerate. Therefor, we
should just initialize it to valid. Since it is cleared to zero initially, this is safe.
Differential Revision: https://phabricator.services.mozilla.com/D151896
mSnapTargets stores the ids for all candidate snap taget elements in this scroll
container. Before this change, we collect the ids when we snap or re-snap on the
main-thread. It's used to check whether the last snap target ids comming from
APZ are not stale or not. So if we haven't done any snapping or re-snapping on
the main-thread, we mis-consider all incoming last snap target ids are stale,
thus we fail to re-snap to the position where we snapped on APZ. This issue
had been wall-papered, will be revealed by the next change in this commit series
(we had been unnecessary snappings and re-snappings).
Differential Revision: https://phabricator.services.mozilla.com/D152617
The old code tweaks mIsTopOfPage in ReflowFloat(). However
`aAvailableSize.ISize()` (in containing block's writing-mode) always equals to
ContentISize() because it is computed via ComputeAvailableSizeForFloat().
Therefore, the only reason the floatRI's mIsTopOfPage can be `false` is when
some floats are already being placed, and we only check this in the
`!earlyFloatReflow` branch.
By tweaking mIsTopOfPage bit in FlowAndPlaceFloat(), we can also remove two
unused parameters in ReflowFloat().
This patch shouldn't change the behavior.
Differential Revision: https://phabricator.services.mozilla.com/D151457
The if-branch is incorrect because ShouldAvoidBreakInside() [1] is called via
the parent block instance with float child's ReflowInput as the argument. In
principle, the child frame should report break-before status if it cannot fit
the page/column and wants to avoid breaking. Removing this if-branch is
potentially a behavior change, but it is the correct thing to do. (Note that
ReflowFloat()'s caller FlowAndPlaceFloat() already handles
IsInlineBreakBefore(). If the float frame type already implements break-avoid,
we are fine.)
The else-if branch can never be reached except when the float is a letter frame,
and we've tested that scenario a few lines just before the this added assertion.
The code coverage also shows this branch in never reached.
https://coverage.moz.tools/#revision=e6e2286d2ac25001127a1cf54a87a95fb435c734&path=layout%2Fgeneric%2FnsBlockFrame.cpp&view=file&line=6682
[1] Note: ShouldAvoidBreakInside() is a protected member function, which can
only be called for concrete frame classes inheriting from nsContainerFrame.
Differential Revision: https://phabricator.services.mozilla.com/D151456
There is some advantage to creating the float's ReflowInput in
FlowAndPlaceFloat().
1. ReflowFloat() doesn't need to output the float's margin and offset via the
output arguments. FlowAndPlaceFloat() can get them from the local ReflowInput
directly.
2. Since we are going to reflow the float, we have to create a ReflowInput
anyway. FloatMarginISize() can take the ReflowInput and be simplified. No need
to waste time to create a separate SizeComputationInput.
Also, delete the comment "Pass floatRS so the frame hierarchy can be
used (redoFloatRS has the same hierarchy)" because I believe it is obsolete.
This patch also lays the foundation for other improvements in the later patches.
Differential Revision: https://phabricator.services.mozilla.com/D151455
This prevents copies and avoids the hack we have to avoid this, which
right now is using nsDependent{C,}String.
Non-virtual actors can still use `nsString` if they need to on the
receiving end.
Differential Revision: https://phabricator.services.mozilla.com/D152519
If we return the snap target in such cases, even though the target position is
unchanged from the original scroll destination, the target will be handled as a
valid last-snapped target element, thus we will try to re-snap to the element's
scroll-snap-align position rather than keeping the scroll position as it is.
Differential Revision: https://phabricator.services.mozilla.com/D152353
ContainSizeAxes::ContainSize and ContainSizeAxes::ContainIntrinsicSize
were just using 0 for the axes with size containment, now they will take
contain-intrinsic-width and contain-intrinsic-height into account.
The WritingMode parameter is replaced with a nsIFrame from which the
properties are retrieved.
There are various places that aren't currently using these functions, so
the effect of this patch is rather minimal, but some cases of the new
test are now passing.
Differential Revision: https://phabricator.services.mozilla.com/D152355
In order to support record the last user input for touch given APZ won't
synthesize mouse event for touch in parent process. Using pointer event could
support pen input nicely, too.
Differential Revision: https://phabricator.services.mozilla.com/D151282
In order to support record the last user input for touch given APZ won't
synthesize mouse event for touch in parent process. Using pointer event could
support pen input nicely, too.
Differential Revision: https://phabricator.services.mozilla.com/D151282
A disabled form controls cannot be focused, and its frame selection is different
from the one for not-editable content. Use GetLastFocusedFrameSelection() (added
in Bug 253870) to get the correct frame selection that is visible to the user.
Add some basic tests for disabled <textarea> such as long pressing to select,
dragging, etc. They should behave the same as normal <textarea>.
Differential Revision: https://phabricator.services.mozilla.com/D151800
We don't handle the first touchmove event differently, so I think we should do
the same thing for pointermove event, otherwise, we might fire a pointermove event
without a touchmove event for the first touch action after touchstart if the touch
postition isn't changed.
Depends on D152152
Differential Revision: https://phabricator.services.mozilla.com/D152153
In order to support record the last user input for touch given APZ won't
synthesize mouse event for touch in parent process. Using pointer event could
support pen input nicely, too.
Differential Revision: https://phabricator.services.mozilla.com/D151282
We don't handle the first touchmove event differently, so I think we should do
the same thing for pointermove event, otherwise, we might fire a pointermove event
without a touchmove event for the first touch action after touchstart if the touch
postition isn't changed.
Depends on D152152
Differential Revision: https://phabricator.services.mozilla.com/D152153
Manage their shadow style per-window instead. It is a bit unfortunate, but
alas, seems to work, and we had existing code for various workarounds, so it's
not too gross.
The menulist special-case isn't needed anymore, menulists always have
eTransparencyTransparent nowadays on Windows.
Differential Revision: https://phabricator.services.mozilla.com/D151994
While I'm here, rename the local variable `styleMargin` to `margin` to make the
naming consistent with the `padding` naming in this patch.
Differential Revision: https://phabricator.services.mozilla.com/D152203
It doesn't fill the ancestors of the first frame if aCommonAncestor is
null, which means that we get garbage afterwards.
MANUAL PUSH: Relanding of old patch.
Keep a separate list of animations in the timeline that are hidden by
content visibility. This allows the DocumentTimeline to disconnect from
the refresh driver when all animations are hidden and prevents ticking
hidden animations in general.
Differential Revision: https://phabricator.services.mozilla.com/D150764
gfxFontCache acquires and releases its mutex during various operations.
In order to keep the state internally consistent, we should only release
the lock after the full operation is complete. This involves moving the
deletion of gfxFont to outside the lock via a temporary discard array.
The expiration state should not be protected by the gfxFont's mutex
since we don't hold it during most operations. Instead we should hold
gfxFontCache's mutex because then we can guarantee the operation is
atomic, particularly when a worker wants a font, and the main thread is
aging the generations.
When a font is returned from gfxFontCache, we now return it already
removed from the tracker, and with its refcount updated. This avoids any
potential races between the expiration timer and a worker accessing the
font, as well as simplying the callers so they don't need to be aware of
addref-ing manually in case the result is to be discarded (so that it
gets readded to the tracker).
Differential Revision: https://phabricator.services.mozilla.com/D151821
gfxFontCache acquires and releases its mutex during various operations.
In order to keep the state internally consistent, we should only release
the lock after the full operation is complete. This involves moving the
deletion of gfxFont to outside the lock via a temporary discard array.
The expiration state should not be protected by the gfxFont's mutex
since we don't hold it during most operations. Instead we should hold
gfxFontCache's mutex because then we can guarantee the operation is
atomic, particularly when a worker wants a font, and the main thread is
aging the generations.
When a font is returned from gfxFontCache, we now return it already
removed from the tracker, and with its refcount updated. This avoids any
potential races between the expiration timer and a worker accessing the
font, as well as simplying the callers so they don't need to be aware of
addref-ing manually in case the result is to be discarded (so that it
gets readded to the tracker).
Differential Revision: https://phabricator.services.mozilla.com/D151821
A disabled form controls cannot be focused, and its frame selection is different
from the one for not-editable content. Use GetLastFocusedFrameSelection() (added
in Bug 253870) to get the correct frame selection that is visible to the user.
Add some basic tests for disabled <textarea> such as long pressing to select,
dragging, etc. They should behave the same as normal <textarea>.
Differential Revision: https://phabricator.services.mozilla.com/D151800
All its members are optional, so we can just use it as a plain struct
rather than Maybe<> all around, which simplifies the code and prevents
silly bugs like bug 1779592.
Mostly automatic via:
rg -l 'SVGImageContext' . | xargs sed -i 's/Maybe<SVGImageContext>/SVGImageContext/g'
With trivial build fixes.
Not intended to change behavior.
Differential Revision: https://phabricator.services.mozilla.com/D151846
That was about XBL constructors being able to run script. But XBL is
gone and this should just be wasted work.
I want to land this in preparation for container queries substantially
changing the model here.
Differential Revision: https://phabricator.services.mozilla.com/D151495
When something switches to display: none, right now we rely on
StopAnimationsForElementsWithoutFrames(), which posts a restyle and the
previous ProcessPendingRestyles call was papering over it.
For other elements in the display none subtree it doesn't matter,
because we don't keep their styles around, but for the display: none
element themselves we do need to update transitions on time.
We could, possibly more generally, remove
StopAnimationsForElementsWithoutFrames() altogether and cancel
animations when we clear style data, perhaps... But that's probably
worth a follow-up.
Differential Revision: https://phabricator.services.mozilla.com/D151600
I don't think why we have a mobile stylesheet (IIUC Android doesn't have
tooltips...), but I noticed that most tooltip styles are the same and it
should be doable to just unify them in xul.css.
We can't keep the platform-specific bits on their own stylesheet because
it loads _before_ xul.css, and thus overrides wouldn't quite do.
Depends on D151640
Differential Revision: https://phabricator.services.mozilla.com/D151641
Even we don't have internal aliases right now (and that seems a bit
silly) we do have pref-gated aliases. An alias ID passed to IsEnabled
with the wrong EnabledState would misbehave, assert, and crash.
Though we don't have such callers in the tree because InspectorUtils
passes only arguments that make us not look at the flags, it seems more
reliable this way.
Differential Revision: https://phabricator.services.mozilla.com/D151594
So we can specify the keyframe-specific composite operation. However,
these is a spec issue about the default composite for CSS Animations:
https://github.com/w3c/csswg-drafts/issues/7476.
I choose to use auto as the default composite for missing keyframes to match
the definition in web-animations-1 because I think this makes more sense:
> If the keyframe-specific composite operation for a keyframe is not set, the
> composite operation specified for the keyframe effect as a whole is used for
> values specified in that keyframe.
Differential Revision: https://phabricator.services.mozilla.com/D150808
Let nsAnimationManager takes animation-composition into account.
Note: This doesn't support animation-composition on each keyframes.
Differential Revision: https://phabricator.services.mozilla.com/D150807
This patch introduces animation-composition longhand but we don't
accept it in @keyframe rule for now. I will support this for @keyframe
in the patch series.
Besides, the shorthand of animation doesn't include animation-composition.
The spec issue is: https://github.com/w3c/csswg-drafts/issues/6946.
We could fix the shorthand once this spec issue gets updated.
Differential Revision: https://phabricator.services.mozilla.com/D150299
Since callers want just an effective color to compute whether it's dark,
we simplify the API a bit too.
This makes sure we find the dark background in plain text documents.
Differential Revision: https://phabricator.services.mozilla.com/D151018
And remove one unused caller.
This might change behavior of some selection contrast checks and backplating
which will potentially use the right background-color after this patch. The
next patch ensures this is also accounted for for scrollbars.
Unfortunately selection contrast checks are non-trivial to test because we only
do the contrast check with system colors, and we'd need a default selection
color close to the highlight color to do this.
Differential Revision: https://phabricator.services.mozilla.com/D151017
That was about XBL constructors being able to run script. But XBL is
gone and this should just be wasted work.
I want to land this in preparation for container queries substantially
changing the model here.
Differential Revision: https://phabricator.services.mozilla.com/D151495
We can't do likewise for reftests and web platform tests because
those test suites disable apz.allow_zooming by default on android.
Differential Revision: https://phabricator.services.mozilla.com/D151576
This doesn't change behavior but makes the next patch simpler, and makes
the ignore-scrollframe and non-ignore-scrollframe code-paths match.
Differential Revision: https://phabricator.services.mozilla.com/D151473
The loaders need to be destroyed on the main thread. Assertions for
gfxUserFontSet and gfxFontFamily need to be updated for workers.
Depends on D151342
Differential Revision: https://phabricator.services.mozilla.com/D151343
This is necessary for when we want to draw text with Canvas 2D and a
user font. This ensures the necessary font families are populated prior
to processing the text run.
Differential Revision: https://phabricator.services.mozilla.com/D151342
The loaders need to be destroyed on the main thread. Assertions for
gfxUserFontSet and gfxFontFamily need to be updated for workers.
Depends on D151342
Differential Revision: https://phabricator.services.mozilla.com/D151343
This is necessary for when we want to draw text with Canvas 2D and a
user font. This ensures the necessary font families are populated prior
to processing the text run.
Differential Revision: https://phabricator.services.mozilla.com/D151342
The old code in AddFloat() used to call nsBlockFrame::ComputeFloatISize() to
compute a float's inline-size, compare it with current line's available
inline-size, and determine whether FlowAndPlaceFloat() should be called.
However, it doesn't handle an orthogonal float with an auto block-size.
Luckily, FlowAndPlaceFloat() already has logic dealing with orthogonal
floats (bug 1141867), so this patch defers the decision to place a float below
the current line until the float's margin inline-size is computed in
FlowAndPlaceFloat().
Differential Revision: https://phabricator.services.mozilla.com/D151209
This patch is a preparation for the next part, and doesn't change the behavior
yet.
FlowAndPlaceFloat() is used to return true and false. This patch changes its
return value `true` to `PlaceFloatResult::Placed` and `false` to
`PlaceFloatResult::ShouldPlaceInNextContinuation`.
In the next part, we'll move the logic dealing with "below the current line
floats" into FlowAndPlaceFloat(), and make it return
`PlaceFloatResult::ShouldPlaceBelowCurrentLine`.
Differential Revision: https://phabricator.services.mozilla.com/D151208
First of all, `nsBlockFrame::AdjustFloatAvailableSpace()` is misleading. It
doesn't adjust the argument `aFloatAvailableSpace` at all, nor does it use any
fields in nsBlockFrame. It simply returns the available space in the parent
block's content area. Thus, I move it into BlockReflowState, and have it return
the available size rather than a rect because a size is sufficient for reflowing
a float.
Also, nsBlockFrame::ReflowFloat() only cares about the available size, but not
the position of the available space, so it is sufficient to pass a LogicalSize
computed by the new method ComputeAvailableSizeForFloat().
In FlowAndPlaceFloat(), there is a loop searching for a wide enough band to
place the float. We don't need to adjust availSize every time mBCoord is changed
in the loop. We can just call ComputeAvailableSizeForFloat() to get a new
available size before reflowing the float in the `!earlyFloatReflow` branch.
This patch shouldn't change the behavior.
Differential Revision: https://phabricator.services.mozilla.com/D151207
In FlowAndPlaceFloat(), condense two identical assertions about float frame
parent into one.
FlowAndPlaceFloat() calls ReflowFloat() only once, either an early reflow (when
`earlyFloatReflow` is `true`) or a late reflow (when `earlyFloatReflow` is
`false`), so the reflow status is always fresh.
Differential Revision: https://phabricator.services.mozilla.com/D151203
The `widget->DispatchInputEvent` codepath only works in gecko CI
configurations, so to allow this to be used for e.g. WebDriver
implement a path that doesn't go via the parent process.
Differential Revision: https://phabricator.services.mozilla.com/D150632
The existing frame label was reusing the function name, but we already
have it when using native stacks. Renaming it to a more understandable
name should make it easier for our javascript developers users without
impairing gecko developers.
Differential Revision: https://phabricator.services.mozilla.com/D150976
aIsAdjacentWithBStart is used to clear the mIsTopOfPage bit for the ReflowInput
argument `aFrameRI`. However, ReflowBlock() already has aState argument to query
IsAdjacentWithBStart(), so there's no need for aIsAdjacentWithBStart argument.
Differential Revision: https://phabricator.services.mozilla.com/D150832
Use the animation id from the stacking context to find the hit-testing tree node
for hit tests of elements that are sticky positioned. Then use this hit-testing
tree node reference to apply APZ transforms if the sticky positioned element is
stuck to the root content.
Differential Revision: https://phabricator.services.mozilla.com/D150047
## Summary
Pass the fixed position element animation id through webrender, returning the
the animation id in the hit-test result if the element is a fixed position
element. This animation id then can be used to lookup the relevant Hit-Testing
Tree Node, which can be used to find the fixed (or sticky) position side bits.
## Motivation
Sticky content can be currently stuck to the root content or not, based on the
scroll position. As a result, when hit testing sticky content, APZ needs both
the sticky position side bits and additional information to determine if the
element is currently stuck to the root content. This is needed to fix the
hit-testing of sticky position content when a APZ transform is being applied,
such as overscroll and hiding the dynamic toolbar.
## Implementation
The information needed to determine if a element is currently stuck to the root
content and the fixed/sticky position side bits is already stored in the
hit-testing tree node. Any hit test result should have a corresponding
hit-testing tree node entry. When a hit-test result contains a animation id and
a hit-testing tree node is found, we can store a pointer to this node and use
this to check the fixed/sticky position side bits. Something similar is already
done for hit test results when a scrollbar is hit.
Differential Revision: https://phabricator.services.mozilla.com/D148648
The basic machinery to trigger re-snap is same as what scroll anchoring does,
queueing a triggering request and flush the queued requests after reflows
finished.
Depends on D148862
Differential Revision: https://phabricator.services.mozilla.com/D148863
There are some call sites of ScrollTo involving will a GetSnapPointForDestination
call. For re-snapping, we need to inform not only the snap point but also the
snap target id(s). To do it, in subsequent patches in this commit series, we will
change only ScrollToWithOrigin arguments rather than both ScrollTo and
ScrollToWithOrigin.
Depends on D148857
Differential Revision: https://phabricator.services.mozilla.com/D148858
The current implementation of TimelineConsumers contains some unnecessary
complexity due to how it is initialized as a singleton, and the need for it to
be initialized and used in a threadsafe way. This patch attempts to simplify it
by making all members static, and removing the need to explicitly observe
shutdown for cleanup.
In addition, this approach avoids the risk of the type being accessed from
off-main-thread during initialization or shutdown.
Depends on D150442
Differential Revision: https://phabricator.services.mozilla.com/D150443
This patch splits document specific functionality from FontFaceSetImpl
into a new class FontFaceSetDocumentImpl. This will make it easier to
fork FontFaceSetImpl for workers.
Differential Revision: https://phabricator.services.mozilla.com/D147819
This patch merges FontFaceSetImpl and gfxUserFontSet into the same
class. This reduces the level of indirection and in theory makes it
easier to manage future threading issues.
Differential Revision: https://phabricator.services.mozilla.com/D147817
This patch aims to split the implementation details of FontFace(Set)
into FontFace(Set)Impl classes. The Impl variants have threadsafe
refcounting and are intended to be the basis for worker support for
FontFace(Set). We need threadsafe objects to pass around because parts
of the stack can only run on the main thread (network loading of font
data, graphics initialization of a font) even if the FontFace(Set)
itself lives on a DOM worker thread. Given the DOM facing objects are
cycle collected, we need additional indirection to support this use
case.
This patch should be a non-functional change.
Differential Revision: https://phabricator.services.mozilla.com/D147505