Skip to content

Rewrite Volmeters in WebGL#1649

Merged
avacreeth merged 16 commits intostaging2from
webgl_volmeters
Apr 23, 2019
Merged

Rewrite Volmeters in WebGL#1649
avacreeth merged 16 commits intostaging2from
webgl_volmeters

Conversation

@avacreeth
Copy link
Copy Markdown
Member

@avacreeth avacreeth commented Apr 19, 2019

We need to put this through a battery of benchmarks, but it looks like this could save us a bunch of CPU.

Comment thread main.js Outdated
}

app.disableHardwareAcceleration();
// app.disableHardwareAcceleration();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it required?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. WebGL does not work with hardware acceleration off. I will remove this rather than commenting out before this is merged.

@holiber
Copy link
Copy Markdown
Contributor

holiber commented Apr 19, 2019

Sometimes I'm just thinking about the idea of having all pre-rendered voltmeters states into a single image and changing the visible area of this image.

@avacreeth
Copy link
Copy Markdown
Member Author

@holiber I'm not sure that would be as efficient. Our original volmeter implementation was based on using CSS transforms, which ended up being less efficient than our most recent Canvas 2D implementation, and significantly less efficient than this WebGL implementation. But if you do have any other ideas you want to try I am all ears and certainly not married to this implementation.

Comment thread app/services/performance.ts Outdated

window['startMeasure'] = () => {
this.measurements = [];
};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll be backing these changes out of this PR. Was just using this to sanity check the performance increases I was seeing.

@holiber
Copy link
Copy Markdown
Contributor

holiber commented Apr 19, 2019

I mean if you have a set of pre-rendered frames in one image you can just change the position of the visible part of the image. So the computer renders the image only once. However, I can't say this way will be more efficient without testing. Just letting know that we didn't try it.
image

@avacreeth
Copy link
Copy Markdown
Member Author

avacreeth commented Apr 19, 2019

Yeah essentially a sprite sheet. My gut tells me using sprites to animate the volmeters with be more expensive. But yes we haven't tried it.

@AppVeyorBot
Copy link
Copy Markdown

❌ build failed Build execution time has reached the maximum allowed time for your plan (60 minutes).

@avacreeth
Copy link
Copy Markdown
Member Author

Looks like our CI machines don't support hardware acceleration, so this will always raise an error there. I am either going to keep the old volmeters as a fallback or just disable it on our CI. We need to do more research on how many users are going to be on machines that won't support WebGL.

@avacreeth
Copy link
Copy Markdown
Member Author

On second thought I'm definitely going to keep the old code as a fallback. It's easy enough to do and will guarantee the best support for the most people.

}

drawVolmeterChannel(peak: number, channel: number) {
private drawVolmeterChannelC2d(peak: number, channel: number) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function drawVolmeterChannelC2d has 33 lines of code (exceeds 30 allowed). Consider refactoring.

@avacreeth
Copy link
Copy Markdown
Member Author

Ok should properly fall back to Canvas 2D now on unsupported machines. The 2 renderers produce visually identical results.

@qlty-cloud-legacy
Copy link
Copy Markdown

Code Climate has analyzed commit 39f4916 and detected 0 issues on this pull request.

View more on Code Climate.

this.drawVolmeterWebgl(volmeter.peak);
} else {
this.drawVolmeterC2d(volmeter.peak);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we pay attention on performance in this PR, we should draw volmeters on requestAnimationFrame event. It allows skipping some frames if CPU is overloaded

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that helps us here. requestAnimationFrame executes the callback before the next paint. In an animation loop using requestAnimationFrame, you would queue up your next requestAnimationFrame from within your callback. This means that effectively your your callback interval matches your paint cycle. As that slows, so does your interval.

However, simply adding a call in this callback to requestAnimationFrame does nothing for us, because the interval is a set 40ms by OBS. Our callback will be called every 40ms by OBS regardless of the paint speed. requestAnimationFrame would not save us any work because we would be using it incorrectly.

A potential solution could be to separate the OBS callback and the render callback. So we simply store the latest data on the frontend, and then asynchronously run a traditional requestAnimationFrame loop that picks up that data and draws it with WebGL. However I'm skeptical that would actual cause any tangible benefit in CPU usage.

@avacreeth avacreeth changed the base branch from staging to staging2 April 23, 2019 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants