Handling complex calculation in C++ for better performance in iOS

Hello everyone,

I am trying to optimise my game which has poor performance in iOS native in CC3.8.3. Main issue I have is that I am doing the renderdata(vertices) caculations every frame and updating to the sprite component which is heavy in JS without JIT in iOS.

So checking the possibility to move the heavy calculations to the C++ but having hard time to figure out the way to do it.

Questions -

  • What can I do for moving my gamestate(data required for calculations) from JS code to C++ and have the result back?

  • How much does it affect the performance with data passing from JS to C++ and back. Will it be worth trying this in terms of performance gain.

  • Is it feasible to update the render data directly in the C++ code if I move the calculations to C++ by any way.

Also is there any other component I can use to easily update the renderdata(vertices and indices) that have better performance rather than customising the sprite component and assembler and using spriteframe.vertices to do it since unlike 2.4 the spritetype Mesh is removed in 3.8.

Any alternative approaches are welcome.

Thank you!

Hi @A_S ,

how did you customized Sprite Component and Assembler? What kinds of complex calculation did you do?

Currently, Components and 2D Assemblers are all implemented in TS.

  • What can I do for moving my gamestate(data required for calculations) from JS code to C++ and have the result back?

You could refer to the documentation ( Introduction | Cocos Creator ) to export a C++ class to JS.

  • How much does it affect the performance with data passing from JS to C++ and back. Will it be worth trying this in terms of performance gain.

That depends on how frequently do the data pass from JS to C++ or C++ to JS.
If the data is all numbers, you probably could use share ArrayBuffer strategy to avoid passing large data between languages.

There is a doc ( Optimization of Cross-Language Invocation | Cocos Creator ) here to describe this optimization strategy in engine.

  • Is it feasible to update the render data directly in the C++ code if I move the calculations to C++ by any way.

Sorry, there is no eazy way to archive this since Assembler is only accessable in JS/TS.

Hi @dumganhar ,
Thank you for the reply,

I customised the sprite component to use custom assembler and update the renderdata directly instead of assembler. In the assembler I just update the color and uv in chunk.vb buffer from renderdata and indices from spriteframe.vertices.indices(which I update when calculating the vertices) into chunk.ib. Here I skip updateVertexData() where position, rotation and scale are calculated since I am doing it myself.
Also sometime vary the renderdata length using renderData.resize(vertCount, indexCount)

The calculations are not complex, they are just simple math, but there are quite a large number of vertices that need to calculated every frame and using the sprite.markForUpdateRenderData() to update the changes in every frame.

I am preventing these calculations when the game is idle and getting good performance that time but when user is dragging the screen all the renderData need to be recalculated every frame that is where the performance drop occurs in iOS due to large JS code that needs to run.

Just doing the simple math using C++ might not be effective since there would be multiple calls from C++ to JS and back every frame right.

Is there any way in JS itself where I can get the vertex and index buffer using C++ shared memory and directly update the buffers in JS without updating the renderdata and then copying it to the buffers.

Hi @A_S ,Thanks for your feedback. Perhaps rewriting the 2d assembler code in c++ is an option to optimize the performance on iOS.
I’m also wondering how pool performance you got. Is it possible to update a simple demo that I could profile by?

Hi @dumganhar,
Can you give more detail on where can I update the renderdata or buffer in C++ or should I send it back to JS.

Poor in the sense less than 30 fps while touchmoving on screen and sometimes very sluggish that the screen kind of jumping in iOS instead of smooth movement unlike android.
Also sometimes there are some other gamestate calculations that are heavy as well but currently the performance even without that is very low.

Meantime I will try to create a simple demo to reproduce the issue.

Hi @A_S , as I mention that 2d assemblers are all implemented in TS, so there is no better way to do that in C++. Did you profile your code and check where the performance hotspots are?

Yep , a demo will make me know more about how did you write the code and perhaps we could find a better approach to improve the performance.