0
\$\begingroup\$

I'm currently making a 2D RPG in pure Java (yes, I know other frameworks/engines exist xD).

I just created a resizing algorithm and I've noticed that different resolutions result in different FPS counts.

Before I get into the details, I have implemented a few optimization methods.

  • All tiles are batched together into a single image as they are loaded into memory
  • All images are loaded into memory so no disk loading is happening while the game is rendering.
  • The game renders everything in a (screenWidth by screenHeight) chunk, otherwise the object is not rendered. This is to prevent unnecessary rendering.
  • The game updates at a constant 60 times per second, while the FPS varies with no upper cap.

Now that that's all out of the way, here's the problem.

When the game is at its native resolution (640x360), I get about 840 FPS. When the game is maximized to full screen(1920x1017), I get about 100 FPS.

I tried to debug this by taking out all parts of the render method individually (eg. tilemap, map objects, player, etc). and nothing seemed to make a significant impact. Eventually, I narrowed it down by stripping my render method AND my update method, leaving me with just graphics.fillRect(0, 0, WIDTH, HEIGHT) where width and height are the screen dimensions.

  • With a screen resolution of 640x360, I get about 2700FPS.
  • With a screen resolution of 1920x1017, I get about 290FPS.

Therefore, by process of elimination, I have figured out that the bulk of the problem is not due to my render method or my update method, and that it must be caused by the graphics object needing to simply render more pixels.

Could someone let me know if there is any way to eliminate these differences in the FPS with different resolutions (keeping in mind the optimizations I have already put in place) or if the differences are inevitable due to the nature of the java.awt.Graphics2D object?


Edit: I ran my application through JProfiler (which I'm completely new to, so please bear with me for any difficulties).

Here is a screenshot of the JProfiler looking at CPU views -> Hotspots when my game resolution is 640x360.

JProfiler CPU Views Hotspots, Game Resolution 640x360

and here is one when my game resolution is 1920x1017.

JProfiler CPU Views Hotspots, Game Resolution 1920x1017

As you can see, java.awt.Graphics2D.drawImage, java.awt.image.BufferStrategy.show and java.awt.Graphics2D.fillRect take the most space. This is what I suspected, as I knew the image rendering would take some time. However, I noticed an interesting trend that occurred in both screen resolutions:

  • java.awt.Graphics2D.fillRect takes approximately twice the amount of average time per invocation than java.awt.Graphics2D.drawImage.

I know that it is the average call time, so of course some images will not always be the same size as the screen, but it still made me curious if that had something to do with it.

As Pikalek said, a higher resolution has more data to push, but is there something else that might be causing these differences in FPS? Poor optimization in some spots perhaps?


One more edit, sorry...

I ran the program after removing graphics.fillRect(0, 0, WIDTH, HEIGHT), and the FPS differences did not make much of a difference. Here are the results with everything rendered.

  • Resolution of 640x360: Approximately 960FPS
  • Resolution of 1920x1017: Approximately 115FPS
\$\endgroup\$
9
  • 4
    \$\begingroup\$ Ask a profiler. It's the only way to check resource consumption in a reliable manner. \$\endgroup\$
    – Almo
    Jun 21, 2021 at 17:26
  • 1
    \$\begingroup\$ 1920x1017 is literally an odd resolution - is it natively supported by your hardware? At any rate, when you multiply out the resolutions by the update rate, the results aren't hugely different. The low res is better, but not by order of magnitude or even double, it's 6.22x10^8 versus 5.66x10^8. A higher resolution has more data to push. \$\endgroup\$
    – Pikalek
    Jun 21, 2021 at 18:15
  • \$\begingroup\$ It's actually 1920x1080, but when I trim off the height of the menu bar and the windows taskbar, it becomes 1017px instead of 1080. \$\endgroup\$
    – ElliottV4
    Jun 21, 2021 at 18:18
  • 2
    \$\begingroup\$ 1920 * 1017 is just a shade under 2 million. 640 * 360 is about 230000. There's nothing to debug here : you're drawing ~10 times as many pixels so you should expect a roughly commensurate performance drop. \$\endgroup\$ Jun 21, 2021 at 18:43
  • 1
    \$\begingroup\$ That's getting close to needing to be a separate question, but most games typically upper-bound rendering speed to either a commonly-used fixed value, such as 60fps, or to the monitor's refresh rate. Any of your players running on battery power will also thank you for doing this. \$\endgroup\$ Jun 21, 2021 at 19:07

1 Answer 1

2
\$\begingroup\$

1920 * 1017 is just a shade under 2 million. 640 * 360 is about 230000. There's nothing to debug here : you're drawing ~10 times as many pixels so you should expect a roughly commensurate performance drop.

If the player wants to play at that maximum resolution, should you implement some form of an upper FPS cap for all resolutions so they don’t have to think its some sort of code-based issue when they see the 10x increase/decrease in performance? Would this fix have any negative implications?

Most games typically upper-bound rendering speed to either a commonly-used fixed value, such as 60fps, or to the monitor's refresh rate. Any of your players running on battery power will also thank you for doing this.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .