diff --git a/packages/fiber/src/core/loop.ts b/packages/fiber/src/core/loop.ts index df691a859c..7915467b4b 100644 --- a/packages/fiber/src/core/loop.ts +++ b/packages/fiber/src/core/loop.ts @@ -97,6 +97,7 @@ interface Loop { export function createLoop(roots: Map): Loop { let running = false + let useFrameInProgress = false let repeat: number let frame: number let state: RootState @@ -110,6 +111,7 @@ export function createLoop(roots: Map): Loop { flushGlobalEffects('before', timestamp) // Render all roots + useFrameInProgress = true for (const root of roots.values()) { state = root.store.getState() // If the frameloop is invalidated, do not run another frame @@ -121,6 +123,7 @@ export function createLoop(roots: Map): Loop { repeat += render(timestamp, state) } } + useFrameInProgress = false // Run after-effects flushGlobalEffects('after', timestamp) @@ -139,8 +142,20 @@ export function createLoop(roots: Map): Loop { function invalidate(state?: RootState, frames = 1): void { if (!state) return roots.forEach((root) => invalidate(root.store.getState(), frames)) if (state.gl.xr?.isPresenting || !state.internal.active || state.frameloop === 'never') return - // Increase frames, do not go higher than 60 - state.internal.frames = Math.min(60, state.internal.frames + frames) + if (frames > 1) { + // legacy support for people using frames parameters + // Increase frames, do not go higher than 60 + state.internal.frames = Math.min(60, state.internal.frames + frames) + } else { + if (useFrameInProgress) { + //called from within a useFrame, it means the user wants an additional frame + state.internal.frames = 2 + } else { + //the user need a new frame, no need to increment further than 1 + state.internal.frames = 1 + } + } + // If the render-loop isn't active, start it if (!running) { running = true