Яндекс

Thursday, June 4, 2015

Android port. Current results.

Android port was the last task planned to implement within the schedule of GLideN64 Iniegogo campaign. The planned task duration was one month. The work started in May. Today I can summarize achieved results.

1. GL ES support.

As you know, mobile platform use subset of OpenGL standard API: OpenGL ES. There are five GL ES versions, from 1.0 to 3.1. Most of current Android devices can use GL ES v2.0. Newer devices are GL ES v3.0 compatible. Newest devices with Android 5.01 may have GL ES 3.1 support.

All OpenGL ES version have very different capabilities. GL ES 2.0. is quite old and limited. Nevertheless, all current graphics plugins for N64 emulators for Android use GL ES 2.0. There are two reasons for it:

  1. The plugins developed years ago
  2. 2/3 of users have devices, which capable to run only GL ES 2.0

During development of desktop version I had to use various advanced features of OpenGL. My code was not ready to fit the Procrustean bed of  GL ES v2.0 standard. From the other side GL ES v3.0 was much closer to my existing code. GL ES v3.1 has almost everything, which I used for desktop version. Thus, it was natural to start porting to Android from GL ES v3. That work was finished within one week. I disabled some part of code for GL ES v3.0, and just replaced few functions for GL ES v3.1. My code was integrated with Mupen64Plus AE emulator, and I got all necessary support from emulator's developers. Special thanks to littleguy and Gillou68310. I've got a build, which successfully run on NVIDIA Shield tablet. The build missed texture library for technical reasons, but everything else seems worked fine.
Zelda MM on NVIDIA Shield
I started to test my work on other devices and very soon found that situation with mobile GL is much worse than I thought. NVIDIA Shield is a perfect gem in a world of ugly boulders named mobile GPU. My Galaxy Note 3 is powered by Adreno 330 and claims to be GL ES 3.0 compatible. However it has so poor v3.0 support so I just don't know how to change my code to make it compatible with that piece of hardware.
Super Mario 64 running in GL ES 3.0 mode on Adreno 330
Thus, I was forced to complete mission impossible and port my code to GL ES v2.0

As I said, GL ES 2 is very limited and outdated. I had to disable large part of functionality for it (bye-bye mip-maping emulation), and rewrote remaining part to make it compatible with GL ES 2. I tried to support as much of plugin functionality as possible. Thus, GL ES 2 port supports most of frame buffer emulation features, and has limited noise emulation.
Mario Tennis running on GL ES 2 device

Note, that GL ES v2.0 support allowed to port GLideN64 not only on Android but on other mobile platforms, e.g. Pandora 
Conker BFD on Open Pandora

2. Texture library

Next hard task was port of GLideNHQ texture library, to get texture enhancement and hi-res texture packs support. GLideNHQ uses Boost portable C++ libraries for OS-independent file-system access. Boost works well on desktop OS, but Boost for Android has experimental status. Gillou68310 managed to build Boost for Android, but any attempt to actually use it caused application crash. The only remaining solution was to remove Boost dependency. I rewrote GLideNHQ code, replacing Boost by small custom filesystem library. After that I got texture library working, including hi-res textures support. However, it worked only on Shield tablet.

Texture library code does not use OpenGL functions, and independent of GL version. Thus, it had to work on every Android device. Long debugging revealed the problem: most of Android devices have very limited support for wchar_t* strings. GLideNHQ uses wide strings for correct work with non-ASCII paths and file names on desktop OS. Android supports wide strings on its Java API level. Support on native code level is near zero. You may compile code with wchar_t* strings, but it will not work because most of wchar_t functions do nothing. Thus, I had to write special wrapper to work with wide strings on Android. That finally allowed GLideNHQ to load hires textures on every Android device.

Gillou68310 added port of FreeType library to the emulator, which allowed me to have the same text drawer, as on desktop version.
Hi-res texture pack load

Super Mario 64 with texture pack
Yoshi's Story with texture enhancement


3. Post filter


Final task was post-filter support. Again, GL ES 2 required special code, but it was solved.
Wave Race with Bloom

4. Problems

Currently the main problem is performance. GL ES 2.0 devices are too week to run GLideN64 full speed. Performance depends on GPU. Mali-400 devices work not bad, some games run full speed. PowerVR GPU has slide show performance. GL ES 3 devices usually run full speed.

There are problems with frame buffer emulation. Color/Depth buffer copy works slow even on NVIDIA Shield. Some effects, which work on desktop do not work on mobile version.

Also there are many cases when code is compatible with some GPU, but does not work on other one.
I have only few devices on hands and can not test and fix all cases.

Conclusion:

All tasks planned in Indiegogo campaign are fulfilled. Huge amount of works have been done within several months. Master branch in Git repository contains more than thousand commits. New open-source graphics plugin with unique set of features successfully works on desktop and mobile platforms. Of course, not everything is fine. Not all planned features implemented, not all games run flawlessly. However, I hope that open-source nature of the project will help the project's further development.

Sergey Lipskiy.