Can someone explain double number of draw calls on external monitor?

Hey everyone,

I have an M1 Mac and I’ve noticed a curious thing regarding the PlayCanvas stats. When looking at the stats on an external monitor connected to the laptop I’m seeing approximately a double number of draw calls compared to when I’m looking at the same scene on the laptop’s display and I can’t explain it.
It is enough to just move the browser window from the external display to the laptop display and the number of draw calls halves.
This is intriguing because the number of draw calls are not affected by performance, display refresh rate, etc, they should be just a measure of how much it is drawn during a single frame.

That’s quite interesting, I haven’t seen that before in that way.

The only way I’d get a different number of draw calls across different devices, was when rendering things in a lower interval and not per frame.

@mvaligursky any idea?

No idea, I have not seen this before. Can you reproduce this using examples? https://playcanvas.github.io/

Otherwise, maybe in a simple project?

I couldn’t reproduce it with the engine examples. So this may be an issue on our side, not sure yet, but I’ll try to see if I can reproduce it with a simple project.
Here’s a screenshot of the scene captured from the laptop display:


and then another one from the external monitor:

1 Like

Can you run SpectorJS to verify that this isn’t an issue with the ministats?

PS This world seems so nice!

1 Like

Hmm, now this is strange, enabling Spector.js now it makes the game show the same number of draw calls in both cases (the double number ~600 draw calls).

PS. I’m glad you like the world Leonidas! Thank you!

1 Like

Do you have a script to limit framerate, from 60 to 30 or something like that perhaps? (by skipping every second frame)

We don’t have a FPS limiting script but we do have a “performance tier” script that changes resolution and enables disables some features in the shaders/materials but the number of meshes drawn on the screen should be constant per frame. We don’t have lighting enabled or shadows, it is all custom. Enabling shadows would have been my obvious first look as that would double the number of draw calls for meshes that cast shadows. Im really intrigued by what’s happening, but not being able to reproduce this with the engine examples indicates that it has to do with our setup and code.
I’ll continue investigating and let you guys know what I find.

2 Likes

I spent a bit of time today looking deeper into this. I added a log inside the AppBase._fillFrameStatsBasic method to see what values I get inside

        // total draw call
        this.stats.drawCalls.total = this.graphicsDevice._drawCallsPerFrame;
        console.log(`AppBase._fillFrameStatsBasic: (now: ${now}, dt: ${dt}, ms: ${ms}, dc: ${this.graphicsDevice._drawCallsPerFrame})`);
        this.graphicsDevice._drawCallsPerFrame = 0;

And I got these values on the external monitor

app-base.js:549 AppBase._fillFrameStatsBasic: (now: 18921.917, dt: 0.016680000000000292, ms: 16.68000000000029, dc: 135)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 18938.597, dt: 0.016680000000000292, ms: 16.68000000000029, dc: 135)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 18955.277, dt: 0.016679999999996652, ms: 16.679999999996653, dc: 135)

the FPS on the external monitor is 60
but for the laptop display whose FPS is 120 I get this

app-base.js:549 AppBase._fillFrameStatsBasic: (now: 181221.862, dt: 0.008332999999984167, ms: 8.332999999984168, dc: 134)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 181230.195, dt: 0.00833300000001327, ms: 8.333000000013271, dc: 0)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 181238.528, dt: 0.008332999999984167, ms: 8.332999999984168, dc: 134)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 181246.861, dt: 0.00833300000001327, ms: 8.333000000013271, dc: 0)
app-base.js:549 AppBase._fillFrameStatsBasic: (now: 181255.194, dt: 0.008332999999984167, ms: 8.332999999984168, dc: 134)

the draw calls count (dc) is zero each other frame, this is the reason I’m getting half the number of draw calls, so it seem that the real draw call count it is the one on the external monitor.
I’ve also checked again with Spector and indeed the higher number is the good one and I’m getting that same number when capturing on both displays.
I added the same logging to the engine and ran the examples locally and they’re still showing the correct number all the time on both displays, there is no zero draw call count there.

Investigation continues…

1 Like

So apparently we’re setting the AppBase.autoRender = false and rely on AppBase.renderNextFrame to limit the FPS. This is messing some of the PC stats (drawCalls, cpu, gpu timers). I believe this could be reproduced with the examples as well if a similar FPS rate limiting is applied.

Yeah I can see how something can go wrong there with reporting. Something to investigate on our side for sure one day.

2 Likes