Old performance does not return?

I ported the game from openfl 3.6.1 to openfl 8.9.1 ( Changed Tilesheet to Tilemap ) and the problem.

The problem is described here

I did research

BunnyMark - use_tilemap - 2000 tiles - Android target - old android device:

openfl 3.6.1 : lime 2.9.1 : 60fps
openfl 5.0.0 : lime 4.1.0 : 60fps

openfl 5.1.5 : lime 5.2.1 : 60fps
openfl 5.1.5 (replace 6.0.0) : lime 5.3.0 : 60fps
openfl 6.0.0 : lime 5.3.0 : 15fps

openfl 8.9.1 : lime 7.5.0 : 15fps

openfl < 6.0.0 constant loop time
openfl >= 6.0.0 not constant loop: jumps from 30 to 150 milliseconds

Even such code causes a drop in performance:
graphics.beginBitmapFill ( bitmapData );
graphics.drawRect ( 0, 0, stage.stageWidth, stage.stageHeight );


There are only two backgrounds and the performance drops dramatically.

On new weak smartphones, I observe the same problems.

BunnyMark - use_tilemap - 200 000 tiles - Linux cpp target:

openfl 3.6.1 : lime 2.9.1 : 45fps
openfl 5.0.0 : lime 4.1.0 : 45fps

openfl 5.1.5 : lime 5.2.1 : 45fps
openfl 5.1.5 (replace 6.0.0) : lime 5.3.0 : 45fps
openfl 6.0.0 : lime 5.3.0 : 17fps

openfl 8.9.1 : lime 7.5.0 : 17fps

openfl < 6.0.0 constant loop time
openfl >= 6.0.0 not constant loop

@Vortelio, after reading your post, I’ve actually decided to test one of my games, I’m transferring from Flash/AIR to OpenFL.
Both Android and HTML5 versions are working much slower than Adobe AIR/Flash versions.
Unfortunately, I can’t compare with previous versions of OpenFL.

What are the specs of the Linux machine you are using?

What Android device are you using? There may be a difference between CPU and GPU load (we may stress the CPU more now and the GPU less)

Devices low fps:
ASUS MeMO Pad ME173X
SAMSUNG galaxy s3
SAMSUNG Galaxy J1

Devices normal fps:
LG nexus 5
Xiaomi MI A1
NOKIA 5.1

PC : i5-3570K GeForce GTX 660

Modified BunnyMark test, without animation, only render: https://drive.google.com/open?id=19lKtdjmkjwwaXid0a53F0Bc7Ggv7LoTY

Test results on pc:

openfl 5.1.5 : lime 5.2.1

  • loop time: 24
  • loop time: 23
  • loop time: 24
  • loop time: 24
  • loop time: 23
  • loop time: 24
  • loop time: 23
  • loop time: 24
  • loop time: 23
  • loop time: 24

openfl 6.0.0 : lime 5.3.0

  • loop time: 5
  • loop time: 16
  • loop time: 82
  • loop time: 70
  • loop time: 12
  • loop time: 16
  • loop time: 7
  • loop time: 16
  • loop time: 72
  • loop time: 9
  • loop time: 18
  • loop time: 70
  • loop time: 9
  • loop time: 75

openfl: 8.9.1 lime: 7.5.0

  • loop time: 28
  • loop time: 6
  • loop time: 29
  • loop time: 2
  • loop time: 29
  • loop time: 3
  • loop time: 28
  • loop time: 5
  • loop time: 28
  • loop time: 3
  • loop time: 28
  • loop time: 4
  • loop time: 30

Has the addition of ColorTransform in 6.0.0 really dropped its performance so much?
It looks like a garbage collector, only for each frame.

There are a few values you can use to increase the performance on Tilemap:

We also do not render if we do not detect any changes to the screen, so it’s possible that the loop time is dropping due to not rendering?

1 Like

I was quite excited to try these settings, but none of them seem to be have any significant impact on the render performance on my HTML5 mobile game (which uses about 100 tilemaps) :frowning:

Do you really need to use 100 tilemaps? If you can, put everything in a big atlas PNG (4096x4096 for example) and use only 1 tilemap.

Yes I need them, because I have many UI elements, with several overlays and parenting stuff.
I already use texture atlases when possible, e.g. when all elements in a given overlay can share the same tilemap.

I would really like to update my game to the latest version of openfl. But I cannot do this, as these people. I see a lot of topics on this forum where people use the legacy version. The more developers move to the new version, the better for openfl.

My game is made for people with low incomes, and it is popular in their respective countries, where the whole family has one weak Android device.And I cannot allow the game to stop working for so many people.

BunnyMark - 200 000 tiles - Linux cpp target:

I use openfl_always_render to get stable frames

openfl 3.6.1 : lime 2.9.1 : legacy TileSheet

  • 60 fps
  • loop time: 15ms
  • graphics.drawTiles time: 4ms
  • prepare for rendering: 26% of loop time
  • rendering 11ms Good

openfl 6.0.0 : lime 5.3.0 Tilemap

  • 15 fps
  • loop time: 70ms
  • __bufferData update: 53ms
  • prepare for rendering: 37% of loop time
  • rendering 17ms Bad

openfl 8.9.1 : lime 7.5.0 Tilemap

  • 37 fps
  • loop time: 27ms
  • Context3DTilemap render() time: 27ms
  • Context3DTilemap buildBuffer() time: 20ms
  • Context3DTilemap buildBufferTileContainer() vertexBufferData construct time: 11ms
  • Context3DTilemap buildBufferTileContainer() tilemap.__buffer.flushVertexBufferData() time: 9ms
  • prepare for rendering: 74% of loop time
  • rendering 7ms Amazing

Never need such a number of objects. On powerful devices there is a large headroom for performance, and on weak ones there are big brakes, up to ANR.

Perhaps use one Tilemap – you can use multiple TileContainer objects to use different atlases?

It looks like a problem in Android devices. Incredible magic happens. The loop is completely different from the pc.

BunnyMark - 2000 tiles - Android target - openfl 8.9.1 - lime 7.5.0 - Tilemap:

high performance device :

60 fps

  • Context3DTilemap buildBuffer() time: 3ms
  • Context3DTilemap render time: 9ms
  • loop time: 17ms
  • +8ms vsync?

  • Context3DTilemap buildBuffer() time: 3ms
  • Context3DTilemap render time: 8ms
  • loop time: 16ms
  • +8ms vsync?

low performance device :

14~17 fps

  • Context3DTilemap buildBuffer() time: 4ms
  • Context3DTilemap render time: 5ms
  • loop time: 17ms
  • +12ms vsync?

  • Context3DTilemap buildBuffer() time: 5ms
  • Context3DTilemap render time: 6ms
  • loop time: 140ms
  • +134ms vsync + magic ?

  • Context3DTilemap buildBuffer() time: 5ms
  • Context3DTilemap render time: 8ms
  • loop time: 34ms
  • +26ms vsync + magic ?

Rendering is fast, but what kind of magic interferes with the loop?

I wonder If this could be a frame update timing issue rather than some inherent performance problem?

There was / is a similar problem in Android + OpenFL Legacy (<= v3.6.1). With Legacy, If you have vsync enabled and set the frame rate to 61fps you get nice smooth performance, 60fps is choppy.

So try upping the frame rate (with vsync enabled) and see If things improve, If not then It It’s probably a GC issue. You could use hxScout and see If GC sweeps tally with the frame drops.

Unfortunately, this did not help.

Revealed another pattern. Abnormal behavior is observed on all low performance devices with 1GB ram. There is no anomaly on the low performance device with 2GB ram.

lime._internal.backend.native.NativeWindow.contextFlip from 70ms to 330ms

Have you tried another version, like openfl 8.4.0? I’ve noticed performance dropping a lot for tillemap after the change to Stage3D.

Unfortunately, this did not help.

Everything is much easier.
Plain code without Tilemap drops fps to 38:

package;

import openfl.display.Sprite;
import openfl.display.BitmapData;
import openfl.display.Bitmap;

class Main extends Sprite {

	private var bitmap : Bitmap;
	
	public function new () {
		
		super ();

		bitmap = new Bitmap (new BitmapData ( stage.stageWidth, stage.stageHeight, true, 0xFF00FFFF  ) );
		addChild ( bitmap );
		addChild ( new openfl.display.FPS() );
	}
}

In the openfl legacy, on the same device, I had 2-3 such backgrounds and many Tilesheet sprites at 60 fps.

This is a problem with SDL. I found a lot of posts with these symptoms on the Android platform, and they all have no solution.

2 Likes

I guess I’ll stick with Legacy for a bit longer then :S

There is such a game - VVVVVV. It is made using SDL. This is how it works on my test device:

From 27 to 31 FPS. Very ragged frametime with very simple graphics. OpenFL Legacy can draw a more complex picture with 60 FPS on the same device.
Is it a dead end?

I’m not sure if this is related, but I had to fix low performance and even crashes after few hours of gameplay for a port of my game for the Switch, it’s made with openfl/Starling/Haxe & lime-switch (private repo)
I found an issue with the latest Lime, including SDL.
Here is how I fixed it for windows and Switch as it seems to be active on both.
Search for the file SDL_spinlock.c in you Lime library.
Change SDL_AtomicLock function to simply this
SDL_AtomicLock(SDL_SpinLock *lock)
{
SDL_AtomicTryLock(lock);
}
I don’t think it will work for all of you, but it’s an easy fix and worked for me.
You probably have to do this in console after the change
Lime rebuild windows -clean -v
Hope it helps, again I’m not sure what I’m doing, crashes point to this on Switch but it works for me.

1 Like