26

I have an application created with LibGDX. I can run the application on the desktop and it runs at 90 fps @1080p.

On Firefox it runs at 40-50 fps @1080p (maximized window).

On Chrome it runs at 30 fps @1080p (maximized window).

However on Chrome, if I lower the resolution, the performance doubles (to 60fps). On Firefox this does not happen. What can be the cause of this?

I am using webkitRequestAnimationFrame.

As shown, I know my PC can handle the resolution fine.

Edit

I'm trying to apply the tips below, although they seem aimed at mobile GPUs mostly.

Source: https://wiki.mozilla.org/Platform/GFX/MobileGPUs#Memory_Bandwidth

Always call glClear immediately after glBindFramebuffer

See the Adreno 200 document, section 3.2.1: "it is imperative to (a) use clears when switching Frame Buffer Objects (FBOs) to avoid having the driver tries to save/restore GMEM contents, and (b) always clear the depth-buffer at the start of a frame."

That makes sense, so we should always do it. Concretely, this means that we should do a glClear after every glBindFramebuffer call, ideally right after it, or at least before any draw-call.

Framebuffer bindings are expensive

Changing the framebuffer binding forces immediately resolving the rendering of the current framebuffer. Therefore it is important to sort rendering to minimize framebuffer bindings. The Adreno 200 document, Section 3.2.4, has a useful explanation.

Edit

The above did not make a notable difference.

Edit

I have a feeling this problem arises due to the GLSL compiler. I don't have a lot of knowledge on the subject, but I believe GLSL for OpenGL ES is compiled to regular GLSL, with some browser specific code. It could be that Chrome compiles less than optimal and causes fragment shading to slow the program down at higher resolutions.

If someone has some tips on how to make sure that this compilation is optimalized, I could try that out and see if it fixes the problem.

Edit

The problem doesn't seem prevalent in Chrome on Windows with a Intel HD graphics 4000+ chipset. Chrome version: 40.0.2214.111 m. Low resolution: 45fps~. High resolution: 30 fps steady.

My original test case was with Chrome on Ubuntu with a GTX 650. Chrome version will be added later.

Edit

Version of Chrome which displays this problem: 40.0.2214.111 (64-bit) on Ubuntu on a GTX 650 graphics card.

Edit

On the same PC with GTX 650, under Windows 7, the same application runs at 60fps steady under Chrome. Since under Ubuntu the application compiled to Java runs fine at 90fps, I believe it can't be a Linux driver issue, but rather is an issue with the Linux version of Chrome.

Edit

I've sent a bugreport to Chrome about this.

RobotRock
  • 4,211
  • 6
  • 46
  • 86
  • Have you tried to compare the chrome://gpu/ from Linux and Windows to see if they have different Problems Detected? In addition, check there if Chrome/Ubuntu supports hardware acceleration. Moreover, checks if the problem on Chrome/Ubuntu is actually the Rendering.. maybe its something in another part of the code. I would like to suggest, maybe its a good idea to send an email to [Khronos Group mailing list about WebGL](https://www.khronos.org/webgl/public-mailing-list/). – wendelbsilva Feb 17 '15 at 20:59
  • 1
    Are you calling `gl.getError()` or `gl.readPixels` in your render loop? Both of those will kill perf. Are you uploading large amounts of data (like video)? In general you're going to find WebGL slower than native because WebGL canvas's are composited into the webpage. For a fullscreen canvas that's an extra fullscreen draw. On top of that requestAnimationFrame is limited to 60fps (or the refresh rate of your monitor). If you want to check time you should check how many milliseconds were used or left every frame, not how many frames per second since the monitor can't display them – gman Feb 18 '15 at 02:10
  • 2
    On windows WebGL uses DirectX and transpiled HLSL shaders through the [ANGLE project](https://code.google.com/p/angleproject/). Try running Chrome with the `--use-gl=desktop` flag(without any prior Chrome instances running) and see if you experience the same performance issues. Also without you providing any details about what your application does in terms of rendering this question is unsalvageable. Consider adding the link to the bugreport your filed as it may helps others. – LJᛃ Feb 18 '15 at 04:15
  • @gman I'm not using getError unless debugging. I'm not using glReadPixels either or uploading a lot. – RobotRock Feb 18 '15 at 09:38
  • @LJ_1102 I did add the link to the bugreport, I just removed it from this post to avoid too much traffic; it's a heavy application. I will try your tip. – RobotRock Feb 18 '15 at 09:39
  • The big difference in fps could come from requestAnimationFrame as it tries pretty hard to match your monitor refreshrate. If it fails doing it at 60 it may just switch to 30. Maybe try a setTimeout loop to see how fast you can get. – iSchluff Mar 06 '15 at 10:32
  • 1
    I haven't come across this issue in a while, since I've done a huge revision. I did notice once, that outputting too much log information (I'm not sure what Libgdx uses for that, presumably console.log) causes slowdowns. I might have been doing that before too. – RobotRock Mar 06 '15 at 15:09
  • If all else fails, you can always just embrace the low-res look ;) http://playgroundjs.com/demos/threejs/ – Don McCurdy Apr 06 '15 at 06:00

1 Answers1

1

Not including other things in here, as far as I was into it last time, all those requestAnimationFrame methods are capped at 60fps, and can only go lower than that.

You can test it with this bit: http://cssdeck.com/labs/gvxnxdrh/. You can modify fps var as high as you wish, but animation wont go quicker than 60fps in any browser I had on my desktop.

yergo
  • 4,761
  • 2
  • 19
  • 41
  • I doesn't have anything to do with VSync. For some reason Chrome just doesn't like to update windows with high resolutions. If I have a maximized window, it's 20fps. Maximized window with half the resolution, still 20 fps. However, if I shrink the window to half, it increases fps immensely. Firefox doesn't display this issue. – RobotRock May 05 '15 at 10:37
  • Can't really reproduce that behavior... Wat resolution/window size it starts breaking in chrome? – yergo May 06 '15 at 07:05
  • Framerate is variable with window size (resolution) when you are GPU-limited. It happens in one browser and not the other, mostly likely because of the OpenGL implementation. As for the frequency of requestAnimationFrame ... it depends on CPU and GPU speed (see dev tools in your browser, F12, to determine which is causing the throttling). Btw, FPS is not limited to 60. I'm not sure there is a limit, I've seen it run at 75 on a high end computer – DAG May 15 '17 at 18:15