Skip to content

Commit

Permalink
feat: limit rendering in background to 20fps so it uses less resource…
Browse files Browse the repository at this point in the history
…s (+setting to control that)
  • Loading branch information
zardoy committed May 21, 2024
1 parent 0dfa7c3 commit 2a26679
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 8 deletions.
12 changes: 7 additions & 5 deletions prismarine-viewer/viewer/lib/viewerWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ export class ViewerWrapper {
previousWindowWidth: number
previousWindowHeight: number
globalObject = globalThis as any
stopRenderOnBlur = true
stopRenderOnBlur = false
addedToPage = false
renderInterval = 0
renderIntervalUnfocused: number | undefined
fpsInterval

constructor(public canvas: HTMLCanvasElement, public renderer?: THREE.WebGLRenderer) {
Expand Down Expand Up @@ -44,7 +45,7 @@ export class ViewerWrapper {
this.globalObject.requestAnimationFrame(this.render.bind(this))
}
if (typeof window !== 'undefined') {
// this.trackWindowFocus()
this.trackWindowFocus()
}
}

Expand Down Expand Up @@ -77,11 +78,12 @@ export class ViewerWrapper {
for (const fn of beforeRenderFrame) fn()
this.globalObject.requestAnimationFrame(this.render.bind(this))
if (this.globalObject.stopRender || this.renderer?.xr.isPresenting || (this.stopRenderOnBlur && !this.windowFocused)) return
if (this.renderInterval) {
const renderInterval = (this.windowFocused ? this.renderInterval : this.renderIntervalUnfocused) ?? this.renderInterval
if (renderInterval) {
this.delta += time - this.lastTime
this.lastTime = time
if (this.delta > this.renderInterval) {
this.delta %= this.renderInterval
if (this.delta > renderInterval) {
this.delta %= renderInterval
// continue rendering
} else {
return
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const renderWrapper = new ViewerWrapper(renderer.domElement, renderer)
renderWrapper.addToPage()
watchValue(options, (o) => {
renderWrapper.renderInterval = o.frameLimit ? 1000 / o.frameLimit : 0
renderWrapper.renderIntervalUnfocused = o.backgroundRendering === '5fps' ? 1000 / 5 : o.backgroundRendering === '20fps' ? 1000 / 20 : undefined
})

const isFirefox = ua.getBrowser().name === 'Firefox'
Expand Down
10 changes: 10 additions & 0 deletions src/optionsGuiScheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ export const guiOptionsScheme: {
return <Button label='Guide: Disable VSync' onClick={() => openURL('https://gist.github.com/zardoy/6e5ce377d2b4c1e322e660973da069cd')} inScreen />
},
},
{
backgroundRendering: {
text: 'Background FPS limit',
values: [
['full', 'NO'],
['5fps', '5 FPS'],
['20fps', '20 FPS'],
],
},
},
{
custom () {
return <Category>Experimental</Category>
Expand Down
1 change: 1 addition & 0 deletions src/optionsStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const defaultOptions = {
} as Record<string, [number, number]>,
touchControlsType: 'classic' as 'classic' | 'joystick-buttons',
gpuPreference: 'default' as 'default' | 'high-performance' | 'low-power',
backgroundRendering: '20fps' as 'full' | '20fps' | '5fps',
/** @unstable */
disableAssets: false,
/** @unstable */
Expand Down
20 changes: 17 additions & 3 deletions src/react/OptionsItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const OptionButton = ({ item }: { item: Extract<OptionMeta, { type: 'togg
}, [item.values])

return <Button
data-setting={item.id}
label={`${item.text}: ${valuesTitlesMap[optionValue]}`}
onClick={async () => {
if (item.disabledReason) {
Expand Down Expand Up @@ -107,9 +108,22 @@ export const OptionSlider = ({ item }: { item: Extract<OptionMeta, { type: 'slid
return undefined // default display
}, [optionValue])

return <Slider disabledReason={isDisabled(item) ? 'qs' : undefined} label={item.text!} value={options[item.id!]} min={item.min} max={item.max} updateValue={(value) => {
options[item.id!] = value
}} unit={item.unit} valueDisplay={valueDisplay} updateOnDragEnd={item.delayApply} />
return (
<Slider
label={item.text!}
value={options[item.id!]}
data-setting={item.id}
disabledReason={isDisabled(item) ? 'qs' : undefined}
min={item.min}
max={item.max}
unit={item.unit}
valueDisplay={valueDisplay}
updateOnDragEnd={item.delayApply}
updateValue={(value) => {
options[item.id!] = value
}}
/>
)
}

const OptionElement = ({ item }: { item: Extract<OptionMeta, { type: 'element' }> }) => {
Expand Down

0 comments on commit 2a26679

Please sign in to comment.