@@ -36,7 +36,10 @@ export type Lane = number;
3636export type LaneMap < T > = Array < T > ;
3737
3838import invariant from 'shared/invariant' ;
39- import { enableCache } from 'shared/ReactFeatureFlags' ;
39+ import {
40+ enableCache ,
41+ enableTransitionEntanglement ,
42+ } from 'shared/ReactFeatureFlags' ;
4043
4144import {
4245 ImmediatePriority as ImmediateSchedulerPriority ,
@@ -92,11 +95,12 @@ export const DefaultLanes: Lanes = /* */ 0b0000000000000000000
9295
9396const TransitionHydrationLane : Lane = /* */ 0b0000000000000000001000000000000 ;
9497const TransitionLanes : Lanes = /* */ 0b0000000001111111110000000000000 ;
95- const SomeTransitionLane : Lane = /* */ 0b0000000000000000010000000000000 ;
98+ const FirstTransitionLane : Lane = /* */ 0b0000000000000000010000000000000 ;
9699
97100const RetryLanes : Lanes = /* */ 0b0000011110000000000000000000000 ;
98101
99- export const SomeRetryLane : Lanes = /* */ 0b0000010000000000000000000000000 ;
102+ const FirstRetryLane : Lanes = /* */ 0b0000000010000000000000000000000 ;
103+ export const SomeRetryLane : Lane = FirstRetryLane ;
100104
101105export const SelectiveHydrationLane : Lane = /* */ 0b0000100000000000000000000000000 ;
102106
@@ -111,8 +115,8 @@ export const NoTimestamp = -1;
111115
112116let currentUpdateLanePriority : LanePriority = NoLanePriority ;
113117
114- let nextTransitionLane : Lane = SomeTransitionLane ;
115- let nextRetryLane : Lane = SomeRetryLane ;
118+ let nextTransitionLane : Lane = FirstTransitionLane ;
119+ let nextRetryLane : Lane = FirstRetryLane ;
116120
117121export function getCurrentUpdateLanePriority ( ) : LanePriority {
118122 return currentUpdateLanePriority ;
@@ -498,56 +502,88 @@ export function findUpdateLane(
498502 lanePriority : LanePriority ,
499503 wipLanes : Lanes ,
500504) : Lane {
501- switch ( lanePriority ) {
502- case NoLanePriority :
503- break ;
504- case SyncLanePriority :
505- return SyncLane ;
506- case SyncBatchedLanePriority :
507- return SyncBatchedLane ;
508- case InputDiscreteLanePriority : {
509- const lane = pickArbitraryLane ( InputDiscreteLanes & ~ wipLanes ) ;
510- if ( lane === NoLane ) {
511- // Shift to the next priority level
512- return findUpdateLane ( InputContinuousLanePriority , wipLanes ) ;
505+ if ( enableTransitionEntanglement ) {
506+ // Ignore wipLanes. Always assign to the same bit per priority.
507+ switch ( lanePriority ) {
508+ case NoLanePriority :
509+ break ;
510+ case SyncLanePriority :
511+ return SyncLane ;
512+ case SyncBatchedLanePriority :
513+ return SyncBatchedLane ;
514+ case InputDiscreteLanePriority : {
515+ return pickArbitraryLane ( InputDiscreteLanes ) ;
513516 }
514- return lane ;
515- }
516- case InputContinuousLanePriority : {
517- const lane = pickArbitraryLane ( InputContinuousLanes & ~ wipLanes ) ;
518- if ( lane === NoLane ) {
519- // Shift to the next priority level
520- return findUpdateLane ( DefaultLanePriority , wipLanes ) ;
517+ case InputContinuousLanePriority : {
518+ return pickArbitraryLane ( InputContinuousLanes ) ;
519+ }
520+ case DefaultLanePriority : {
521+ return pickArbitraryLane ( DefaultLanes ) ;
521522 }
522- return lane ;
523+ case TransitionPriority : // Should be handled by findTransitionLane instead
524+ case RetryLanePriority : // Should be handled by findRetryLane instead
525+ break ;
526+ case IdleLanePriority :
527+ return pickArbitraryLane ( IdleLanes ) ;
528+ default :
529+ // The remaining priorities are not valid for updates
530+ break ;
523531 }
524- case DefaultLanePriority : {
525- let lane = pickArbitraryLane ( DefaultLanes & ~ wipLanes ) ;
526- if ( lane === NoLane ) {
527- // If all the default lanes are already being worked on, look for a
528- // lane in the transition range.
529- lane = pickArbitraryLane ( TransitionLanes & ~ wipLanes ) ;
532+ } else {
533+ // Old behavior that uses wipLanes to shift interleaved updates into a
534+ // separate lane. This is no longer needed because we put interleaved
535+ // updates on a special queue.
536+ switch ( lanePriority ) {
537+ case NoLanePriority :
538+ break ;
539+ case SyncLanePriority :
540+ return SyncLane ;
541+ case SyncBatchedLanePriority :
542+ return SyncBatchedLane ;
543+ case InputDiscreteLanePriority : {
544+ const lane = pickArbitraryLane ( InputDiscreteLanes & ~ wipLanes ) ;
530545 if ( lane === NoLane ) {
531- // All the transition lanes are taken, too. This should be very
532- // rare, but as a last resort, pick a default lane. This will have
533- // the effect of interrupting the current work-in-progress render.
534- lane = pickArbitraryLane ( DefaultLanes ) ;
546+ // Shift to the next priority level
547+ return findUpdateLane ( InputContinuousLanePriority , wipLanes) ;
535548 }
549+ return lane ;
536550 }
537- return lane ;
538- }
539- case TransitionPriority : // Should be handled by findTransitionLane instead
540- case RetryLanePriority : // Should be handled by findRetryLane instead
541- break ;
542- case IdleLanePriority :
543- let lane = pickArbitraryLane ( IdleLanes & ~ wipLanes ) ;
544- if ( lane === NoLane ) {
545- lane = pickArbitraryLane ( IdleLanes ) ;
551+ case InputContinuousLanePriority : {
552+ const lane = pickArbitraryLane ( InputContinuousLanes & ~ wipLanes ) ;
553+ if ( lane === NoLane ) {
554+ // Shift to the next priority level
555+ return findUpdateLane ( DefaultLanePriority , wipLanes ) ;
556+ }
557+ return lane ;
546558 }
547- return lane ;
548- default :
549- // The remaining priorities are not valid for updates
550- break ;
559+ case DefaultLanePriority : {
560+ let lane = pickArbitraryLane ( DefaultLanes & ~ wipLanes ) ;
561+ if ( lane === NoLane ) {
562+ // If all the default lanes are already being worked on, look for a
563+ // lane in the transition range.
564+ lane = pickArbitraryLane ( TransitionLanes & ~ wipLanes ) ;
565+ if ( lane === NoLane ) {
566+ // All the transition lanes are taken, too. This should be very
567+ // rare, but as a last resort, pick a default lane. This will have
568+ // the effect of interrupting the current work-in-progress render.
569+ lane = pickArbitraryLane ( DefaultLanes ) ;
570+ }
571+ }
572+ return lane ;
573+ }
574+ case TransitionPriority : // Should be handled by findTransitionLane instead
575+ case RetryLanePriority : // Should be handled by findRetryLane instead
576+ break ;
577+ case IdleLanePriority :
578+ let lane = pickArbitraryLane ( IdleLanes & ~ wipLanes ) ;
579+ if ( lane === NoLane ) {
580+ lane = pickArbitraryLane ( IdleLanes ) ;
581+ }
582+ return lane ;
583+ default :
584+ // The remaining priorities are not valid for updates
585+ break ;
586+ }
551587 }
552588 invariant (
553589 false ,
@@ -563,7 +599,7 @@ export function claimNextTransitionLane(): Lane {
563599 const lane = nextTransitionLane ;
564600 nextTransitionLane <<= 1 ;
565601 if ( ( nextTransitionLane & TransitionLanes ) === 0 ) {
566- nextTransitionLane = SomeTransitionLane ;
602+ nextTransitionLane = FirstTransitionLane ;
567603 }
568604 return lane ;
569605}
@@ -572,7 +608,7 @@ export function claimNextRetryLane(): Lane {
572608 const lane = nextRetryLane ;
573609 nextRetryLane <<= 1 ;
574610 if ( ( nextRetryLane & RetryLanes ) === 0 ) {
575- nextRetryLane = SomeRetryLane ;
611+ nextRetryLane = FirstRetryLane ;
576612 }
577613 return lane ;
578614}
0 commit comments