Jump to content
  • Advertisement

Android Build and Performance

Sign in to follow this  
lawnjelly

1355 views

stats.png.5159edef5e31e77b515c1f52a7c754e8.png

In the last few weeks I've been focusing on getting the Android build of my jungle game working and tested. Last time I did this I was working from Windows, but now I've totally migrated to Linux I wasn't sure how easily everything would go. In the end, it turns out that support for Linux is great, in fact it was easier than getting things up and running on Windows, no special drivers needed.

Definitely Android studio and particularly the emulators seem to be better than last time, with x86 emulators running near native speed, and much quicker APK uploads to the emulators (although still slow to the devices, I gather I can increase this by updating them to high Android version but then less good for testing).

My devices I have at home are an old Cat B15 phone, 800x480 with a GPU that seems to date from 2006(!), a Nexus 7 2012 tablet, and finally an Amlogic S905X TV media player (2017).  Funnily enough the TV box has been the most involved to get working.

CPU issues

My first issue to contend with was I got a 'SIGBUS illegal alignment' error when running on the phone. After tracking it down, it turns out the particular Arm CPU is very picky about the alignment of data. It is usually good practice to keep structures aligned well, but the x86 is very forgiving, and I use quite a few structs #pragma packed to 1 byte, particularly in serialization. Some padding in the structures sorted this.

Next I had spent many hours trying to figure out a strange bug whereby the object lighting worked fine on emulators, but looked wrong on the device. I had a suspicion it was a signed / unsigned issue in values for diffuse light in a shader input, but I couldn't see anything wrong with the code. Almost unbelievably, when I tracked it down, it turned there wasn't anything wrong with the code. The problem was that on the x86 compiler, a 'char' defaults to be a signed char, but on the ARM compiler, 'char' defaults to unsigned!!

This is an interesting choice (apparently on the ARM chip the unsigned may be faster) but it goes against the usual convention for short, int etc. It was easy enough to fix by flipping a compiler switch. I guess I should really be using explicit signed / unsigned types. It has always struck me as somewhat wierd that C is so vague with the in-built types, with number of bits and the sign, given that changing these usually gives bugs.

GPU issues

The biggest problem I tend to have with OpenGL ES devices is the 'precision' specifiers in shaders. You can fill them however you want on the desktop, but it just ignores them and uses high precision. However different devices have different capabilities for lowp, mediump and highp both in vertex and fragment shaders.

What would be really helpful if the guys making the emulators / OpenGL ES on the desktop could allow it to emulate the lower precision, allowing us to debug precision on the desktop. Alas no, I couldn't figure out a way to get this to work. It may be impossible using the hardware OpenGL ES, but the emulator also can use SwiftShader so maybe they could implement this?

My biggest problems were that my worst performing device for precision was actually my newest, the TV box. It is built for super fast decoding video at high resolution, but the fragment shaders are a minimal 10 bit precision affair, and the fill rate is poor for a 1080P device. This was coupled with the problem I couldn't usb connect up to the desktop for debugging, I literally was compiling an APK, putting it on a usb stick (or dropbox), taking to bedroom, installing, running. This is not ideal and I will look into either seeing if ADB will run over my LAN or getting another low precision device for testing.

I won't go into detail on the precision issues, I wrote more on this on a post here:
https://www.gamedev.net/forums/topic/694188-debugging-precision-issues-in-opengl-es-2

As a quick summary, 10 bits of precision in the fragment shader can lead to sampling error in any maths done there, especially in texture coordinate math. I was able to fix some of my problems by moving the tex coordinate calculations to the vertex shader, which has more precision. Then, it turns out that my TV box (and presumably many such chipsets) support an extra high precision path in the fragment shader, *as long as you don't touch the input data*. This allows them to do accurate uv coords on large texture maps, because they don't use the 10 bit precision.

Menus

menus_small.png.e65f7bd82b59c0f29faf6a2419bc7171.png

I've written a rudimentary menu system for the game, with tickboxes, sliders and listboxes. This has enabled me to put in a bunch of debugging features I can turn on and off on devices, to try and find out what affects performance, without recompiling. Another trick from my console days is I have put in some simple graphical performance bars. I record the last 60 frames into a circle buffer and store things like the frame duration, and when certain game tasks took place. In my case the big issue is when a 'scroll' event takes place, as I render horizontal and vertical tiles of the landscape as you move about it.

In the diagram the blue bar is where a scroll happens, a green bar is where the ground scroll happens, and the red is the frame duration. It doesn't show much on the desktop as the GPU is fast, but on the slow devices I often get a dropped frame on the scrolls, so I am trying to reduce this.

bars.thumb.png.b460803835d692003664eeb39ef3ba28.png

I can turn on and off various aspects of the scrolling / rendering to track down what causes performance issues. Certainly PCF shadows are a big ask on mobiles, as is the ground (terrain) shader.

On my first incarnation of the game I pre-rendered everything (graphics + shadows) out to a massive texture at loadup and just scrolled through it as you moved. This is great for performance, but unfortunately uses a shedload of memory if you want big maps. And phones don't have lots of memory.
So a lot of technical effort has gone into writing the scrolling system which redraws the background in horizontal and vertical tiles as you move about. This is much more tricky with an angled landscape than with a top-down 90 degree view, and even more tricky when you have to render shadow maps as you move.
Having identified the shadow map pass as being a bottleneck, I did some quick calculations for my max map size (approx 16384x16384) and decided that I could probably get away with pre-rendering the shadow map to a 2048x2048 texture. Alright it isn't very high resolution, but it beats turning shadows off completely.
This is working fine, and avoids a lot of ugly issues from scrolling the shadow map. To render out the shadow map I render a bunch of 256x256 tiles and copy them to the final shadowmap.

shadows.thumb.png.e5ea4b3a886e719867ca2f5da21bdfe7.png

This fixed some of the slowness, then I realised I could go a step further. Much of the PCF shadows slowdown was from rendering the landscape shadows. The buildings and objects are much rarer so I figured I could pre-render a low-res landscape shadow texture, and use this when scrolling, then only need to do expensive PCF / simple shadows on the static objects, and dynamic objects.

This worked a treat, and incidentally solves at a stroke precision issues I was having with the shadow shader on the 10 bit hardware.

Joysticks

As well as supporting touchscreens and keyboards, I want to support gamepads, so I bought a bluetooth / wireless gamepad for xmas. It works great with the TV box with wireless dongle, unfortunately, the bluetooth doesn't seem to work with my old phone and tablet, or my desktop. So it has been very difficult / impossible to debug to get analog joystick working.

And, in an oversight(?) for the emulator, there doesn't seem to be an option for emulating a gamepad. I can get a D pad but I don't think it is analog. So after some stabs in the dark with docs I am still facing gamepad focus issues so will have to wait till I have a suitable device to debug this.

That's all for now folks! :)

Sign in to follow this  


2 Comments


Recommended Comments

A D-pad is most definitely not analog.  Also, you mentioned needing special drivers on Windows but  not on Linux.  You need to keep drivers updated on both OS's for testing purposes.  I'm using OpenGL also and it is automatically done for me on Windows, so not sure what you mean by that.  Nice update and keep up the good work.

Share this comment


Link to comment
11 hours ago, Mike2343 said:

A D-pad is most definitely not analog.  Also, you mentioned needing special drivers on Windows but  not on Linux.  You need to keep drivers updated on both OS's for testing purposes.  I'm using OpenGL also and it is automatically done for me on Windows, so not sure what you mean by that.  Nice update and keep up the good work.

For the D pad I was trying to cover myself in case I missed something obvious in the emulator. :) It seems an oversight to miss out on emulating a gamepad, it can't be that difficult to do, compared to say the accelerometers etc.

The drivers I was referring to was when I was initially using my Cat B15 phone on windows I seem to remember downloading and installing specific adb driver to get it to work, as the universal adb driver didn't seem to play ball. No idea of whether it was absolutely necessary, as this was a few years ago. e.g. (https://gsmusbdriver.com/cat-b15).

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By JustACicada
      Random Number God has been updated to v1.1.0.
      This is an incremental (although not idle) game about defeating randomized robots by rolling dice and playing cards that alter those dice and their effects.
      Other than performance fixes, the game has been rebalanced from the ground up. Now it should progress in a more fluid fashion. An option to reset the game with a significant boost to your power has been added, allowing you to advance further than you could before.
      There is also now an option to significantly speed up battle animations. Once you learn the rules of the game, a battle can easily take <2 min.
      Windows, Linux: https://justacicada.itch.io/random-number-god
      Android: https://play.google.com/store/apps/details?id=samuelVazquez.randomNumberGod


    • By Tenebris Equum
      i'm game designer without coding skills.
      i came here looking for Companions with Compassion; i must Retrieve mobile gaming industry overview.
      no matter where you live in this World; please step out it's about time. language barrier won't be problem between us.
      express your passion, and join me on this journey i'll talk to you about this Phenomenal project, add me on discord.
      startup is interesting, but im good.
      if this thread inappropriate please shut down the topic thanks.
    • By MiTi
      Dear everyone, this is my newest game, please check out and give me feedback. Thanks for your consideration.

      Overview: Cross n Puzz is a creative and addicting word puzzle game. It not only challenges your brain but also improve memory and other types of cognitive function.

      For IOS: https://itunes.apple.com/app/crossword-puzzle-image/id1435575074

      For Android: https://play.google.com/store/apps/details?id=com.caag.crosswordnpuzzle

      Game trailer: https://www.youtube.com/watch?v=stNuktpJH44&feature=youtu.be
      Crossword Puzzle Image Trailer Official.mp4  
    • By mtjscott
      Hey, so i've created a disk in unity (2D mobile) that will be shot forward if you drag it back and the further you drag it from the start point the more force will be applied to the impulse similar to the 8ball pool drag to shoot mechanic on miniclip. However, when I applied a script that allows the main camera to follow the ball it broke the mechanic since the balls position is calculated through the camera in world space. So I created a bool that locks the camera in place until the ball is released so the calculation would happen before the camera starts to move. This works however the ball now rubber bands back and forwards close to the start position.
       
      If anything needs more explaining then i'd be glad to do so. I've only been coding for about a week so you'll have to bare with me. Any help is appreciated. Thank you very much.
       
      Here's What happens:
      https://gyazo.com/f211e50f32ac59437a93dad7295a14be
      (screencap gif of the game viewer)
       
      Here is the shoot script:
      using System.Collections; using System.Collections.Generic; using UnityEngine; public class Shoot : MonoBehaviour { [SerializeField] GameObject Disc; [SerializeField] float multiplier; Vector3 initPos; private Rigidbody2D rb; public static bool ballIsReleased = false; bool recordingDistanceDragged = false; private void Start() { rb = gameObject.GetComponent<Rigidbody2D>(); initPos = transform.position; } void OnMouseDrag() { recordingDistanceDragged = true; if(recordingDistanceDragged == true) { transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10)); } else { transform.position = initPos; } } void OnMouseUp() { ballIsReleased = true; } private void FixedUpdate() { if(ballIsReleased == true) { rb.AddForce((initPos - transform.position) * multiplier, ForceMode2D.Impulse); Debug.Log("ball is released"); recordingDistanceDragged = false; } else { ballIsReleased = false; } } }  
      Here is the camera follow script:
      using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraFollow : MonoBehaviour { private Vector2 velocity; public float smoothTimeY; public float smoothTimeX; public GameObject player; private void Start() { player = GameObject.FindGameObjectWithTag("Player"); } private void FixedUpdate() { if (Shoot.ballIsReleased == true) { Debug.Log("camera can move"); float posX = Mathf.SmoothDamp(transform.position.x, player.transform.position.x, ref velocity.x, smoothTimeX); float posY = Mathf.SmoothDamp(transform.position.y, player.transform.position.y, ref velocity.y, smoothTimeY); transform.position = new Vector3(posX, posY, transform.position.z); } } }  
    • By sosnol_gaming
      The massively popular memes "Bongo Cat" has been made into a smartphone game!
       
      Welcome to Bongo Cat DUELS! Wild West is waiting for you. Fight vicious enemies, upgrade cat skills and buy new guns.
       
      FEATURES:
       
      -Participate in duels;

      -Get money and experience for winning;
       
      -Open new duels;

      Google Play:
      https://play.google.com/store/apps/details?id=com.IceSky.bongo_cat_duels
      Youtube:
       
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!