in litho-core/src/main/java/com/facebook/litho/MountState.java [2536:2639]
private void performIncrementalMount(
LayoutState layoutState, Rect localVisibleRect, boolean processVisibilityOutputs) {
final boolean isTracing = RenderCoreSystrace.isEnabled();
if (isTracing) {
RenderCoreSystrace.beginSection("performIncrementalMount");
}
final ArrayList<IncrementalMountOutput> layoutOutputTops =
layoutState.getOutputsOrderedByTopBounds();
final ArrayList<IncrementalMountOutput> layoutOutputBottoms =
layoutState.getOutputsOrderedByBottomBounds();
final int count = layoutState.getMountableOutputCount();
if (localVisibleRect.top >= 0 || mPreviousLocalVisibleRect.top >= 0) {
// View is going on/off the top of the screen. Check the bottoms to see if there is anything
// that has moved on/off the top of the screen.
while (mPreviousBottomsIndex < count
&& localVisibleRect.top
>= layoutOutputBottoms.get(mPreviousBottomsIndex).getBounds().bottom) {
final RenderTreeNode node =
layoutState.getRenderTreeNode(layoutOutputBottoms.get(mPreviousBottomsIndex));
final long id = node.getRenderUnit().getId();
final int layoutOutputIndex = layoutState.getPositionForId(id);
if (!isAnimationLocked(node)) {
unmountItem(layoutOutputIndex, mHostsByMarker);
}
mPreviousBottomsIndex++;
}
while (mPreviousBottomsIndex > 0
&& localVisibleRect.top
<= layoutOutputBottoms.get(mPreviousBottomsIndex - 1).getBounds().bottom) {
mPreviousBottomsIndex--;
final RenderTreeNode node =
layoutState.getRenderTreeNode(layoutOutputBottoms.get(mPreviousBottomsIndex));
final LayoutOutput layoutOutput = getLayoutOutput(node);
final int layoutOutputIndex = layoutState.getPositionForId(node.getRenderUnit().getId());
if (getItemAt(layoutOutputIndex) == null) {
mountLayoutOutput(
layoutState.getPositionForId(node.getRenderUnit().getId()),
node,
layoutOutput,
layoutState);
mComponentIdsMountedInThisFrame.add(node.getRenderUnit().getId());
}
}
}
final int height = mLithoView.getHeight();
if (localVisibleRect.bottom < height || mPreviousLocalVisibleRect.bottom < height) {
// View is going on/off the bottom of the screen. Check the tops to see if there is anything
// that has changed.
while (mPreviousTopsIndex < count
&& localVisibleRect.bottom >= layoutOutputTops.get(mPreviousTopsIndex).getBounds().top) {
final RenderTreeNode node =
layoutState.getRenderTreeNode(layoutOutputTops.get(mPreviousTopsIndex));
final LayoutOutput layoutOutput = getLayoutOutput(node);
final int layoutOutputIndex = layoutState.getPositionForId(node.getRenderUnit().getId());
if (getItemAt(layoutOutputIndex) == null) {
mountLayoutOutput(
layoutState.getPositionForId(node.getRenderUnit().getId()),
node,
layoutOutput,
layoutState);
mComponentIdsMountedInThisFrame.add(node.getRenderUnit().getId());
}
mPreviousTopsIndex++;
}
while (mPreviousTopsIndex > 0
&& localVisibleRect.bottom
< layoutOutputTops.get(mPreviousTopsIndex - 1).getBounds().top) {
mPreviousTopsIndex--;
final RenderTreeNode node =
layoutState.getRenderTreeNode(layoutOutputTops.get(mPreviousTopsIndex));
final long id = node.getRenderUnit().getId();
final int layoutOutputIndex = layoutState.getPositionForId(id);
if (!isAnimationLocked(node)) {
unmountItem(layoutOutputIndex, mHostsByMarker);
}
}
}
if (!mLithoView.skipNotifyVisibleBoundsChangedCalls()) {
for (int i = 0, size = mCanMountIncrementallyMountItems.size(); i < size; i++) {
final MountItem mountItem = mCanMountIncrementallyMountItems.valueAt(i);
final long layoutOutputId = mCanMountIncrementallyMountItems.keyAt(i);
if (!mComponentIdsMountedInThisFrame.contains(layoutOutputId)) {
final int layoutOutputPosition = layoutState.getPositionForId(layoutOutputId);
if (layoutOutputPosition != -1) {
mountItemIncrementally(mountItem, processVisibilityOutputs);
}
}
}
}
mComponentIdsMountedInThisFrame.clear();
if (isTracing) {
RenderCoreSystrace.endSection();
}
}