ebiten: Regression - Artifacts and performances

Ebitengine Version

v2.6.0-alpha.4

Operating System

  • Windows
  • macOS
  • Linux
  • FreeBSD
  • OpenBSD
  • Android
  • iOS
  • Nintendo Switch
  • Xbox
  • Web Browsers

Go Version (go version)

go1.18.3 windows/amd64

What steps will reproduce the problem?

(opengl)

What is the expected result?

  • (case 1) Proper tiling and rendering when moving the mouse and after pressing ‘R’ key

  • (case 2) Same or almost equivalent FPS than before*

What happens instead?

  • (case 1) Black bars are showing sometimes, and at the mouse offset after pressing ‘R’ key

  • (case 2) Worse FPS than before*

Anything else you feel useful to add?

This is a single issue containing two things (as discussed on discord), because they both seem to have been introduced by the same commit* https://github.com/hajimehoshi/ebiten/commit/1c09ec5e44727a0c38b605552d93e4d470a128ab This was originally observed on v2.6.0-alpha.4, then found it might come from this specific commit.

  • (case 1) It’s only after this commit that I’m seeing black bars on the gist I linked above.
  • (case 2) Before this commit, I get 3200+ fps with vsync off on a project I’m currently developping, while I get to 1900+ fps right after this commit.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 19 (19 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks! I’ll close this issue for now.

I can confirm that https://github.com/hajimehoshi/ebiten/commit/1ae5e022b65492024cb8dbc365be652a7915c25a solves it for me https://github.com/hajimehoshi/ebiten/commit/98cb77d94f7368588aae39d2be928ab835faffa2 still does, but shows a few less FPS than the first one (measurable but not significant imo: 2500 vs 2800 on the project I’ve been testing)

My current rough understanding is:

  • In internal/atlas, there are two types for backends: source and destination.
  • If an image is used as a rendering destination, this image is moved from a source backend to a destination backend.
  • If an image is used as a source for a while, the image is moved from a destination backend to a source backend.
  • This timing is calculated by usedAsSourceCount and destinationCount
  • After the change 1c09ec5e44727a0c38b605552d93e4d470a128ab, the timing to count destinationCount up was changed. This variable is less likely updated. (only when the image becomes an independent image)
  • Due to this, the image is now much more likely moved from a destination backend to a source backend.
  • The stacktrace @quasilyte showed actually includes putOnSourceBackend. This indicates that an image is moved from a destination backend to a source backend often.

I bumped into this issue as well.

@Zyko0 helped me out in Discord.

I’ll copy some parts of the discussion here for reference. I’ll also come back after my game is released on Steam with some extra info (I can’t spend much time on debugging right now as I’m crunching).


My original question:

If I have a big texture for the background in form of the ebiten.Image (let’s say 3000x3000 pixels), should I chunk it into several smaller images, like 640x640 chunks or whatever or it’s totally fine to use large single images and render only a sub-image from them?

image

I think I’m hitting a big GC pause when Ebitengine works with them. As you can see on this trace graph, there is a certain spike that makes the game freeze for something like 40ms, which is noticeable (it looks like a 1-2 frames drop). Through trial and error, I found out that this issue goes away if I stop rendering the background. The background is a big image as described above.

The trace is (v2.5.4):

github.com/hajimehoshi/ebiten/v2/internal/restorable.(*Image).WritePixels:300
github.com/hajimehoshi/ebiten/v2/internal/restorable.(*Image).ClearPixels:271
github.com/hajimehoshi/ebiten/v2/internal/atlas.(*Image).dispose:659
github.com/hajimehoshi/ebiten/v2/internal/atlas.(*Image).moveTo:234
github.com/hajimehoshi/ebiten/v2/internal/atlas.(*Image).putOnSourceBackend:360
github.com/hajimehoshi/ebiten/v2/internal/atlas.putImagesOnSourceBackend:118
github.com/hajimehoshi/ebiten/v2/internal/atlas.BeginFrame:855
github.com/hajimehoshi/ebiten/v2/internal/buffered.BeginFrame:37
github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrameImpl:107
github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrame:73

This pause only happens once after the texture is generated and rendered a few frames (!) So it’s not the first Draw call, but rather some nth call that causes this to happen, which is surprising. I would expect it to hang during the first texture draw attempt.

Zyko responded with:

Could you try go getting v2.5.0-alpha.12.0.20230228174701-7c0fbce0cfd8 and test again please?

And it did, in fact, solve my issue.

As funny as it may sound, but I can’t reproduce this issue on this version.

Zyko continued:

What about with this commit 1c09ec5e44727a0c38b605552d93e4d470a128ab (just one commit after the one I linked you)

This version does make things go bad.

I minimized (as much as I could) the case for black bars

Is this https://gist.github.com/Zyko0/185f7b625a46cfc4c1df34efad29a6fa?

I’ll take a look, thanks!