docs/README-android.md
author Sam Lantinga <slouken@libsdl.org>
Wed, 26 Sep 2018 10:08:14 -0700
changeset 12229 2fb171be56e0
parent 12141 6b61de046a2f
child 12364 351a67dbe9c6
permissions -rw-r--r--
Updated version to 2.0.9
slouken@10486
     1
Android
gabomdq@9023
     2
================================================================================
gabomdq@9023
     3
slouken@11328
     4
Matt Styles wrote a tutorial on building SDL for Android with Visual Studio:
slouken@11328
     5
http://trederia.blogspot.de/2017/03/building-sdl2-for-android-with-visual.html
slouken@11328
     6
slouken@11659
     7
The rest of this README covers the Android gradle style build process.
slouken@11659
     8
slouken@11659
     9
If you are using the older ant build process, it is no longer officially
slouken@11659
    10
supported, but you can use the "android-project-ant" directory as a template.
slouken@11647
    11
slouken@11328
    12
slouken@11328
    13
================================================================================
slouken@11328
    14
 Requirements
slouken@11328
    15
================================================================================
gabomdq@9023
    16
slouken@12141
    17
Android SDK (version 26 or later)
icculus@10891
    18
https://developer.android.com/sdk/index.html
gabomdq@9023
    19
slouken@12141
    20
Android NDK r15c or later
icculus@10891
    21
https://developer.android.com/tools/sdk/ndk/index.html
gabomdq@9023
    22
slouken@11649
    23
Minimum API level supported by SDL: 14 (Android 4.0.1)
gabomdq@9023
    24
slouken@11647
    25
gabomdq@9023
    26
================================================================================
gabomdq@9023
    27
 How the port works
gabomdq@9023
    28
================================================================================
gabomdq@9023
    29
gabomdq@9023
    30
- Android applications are Java-based, optionally with parts written in C
gabomdq@9023
    31
- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to 
philipp@9066
    32
  the SDL library
gabomdq@9023
    33
- This means that your application C code must be placed inside an Android 
philipp@9066
    34
  Java project, along with some C support code that communicates with Java
gabomdq@9023
    35
- This eventually produces a standard Android .apk package
gabomdq@9023
    36
gabomdq@9023
    37
The Android Java code implements an "Activity" and can be found in:
slouken@11647
    38
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
gabomdq@9023
    39
gabomdq@9023
    40
The Java code loads your game code, the SDL shared library, and
gabomdq@9023
    41
dispatches to native functions implemented in the SDL library:
gabomdq@9023
    42
src/core/android/SDL_android.c
gabomdq@9023
    43
gabomdq@9023
    44
gabomdq@9023
    45
================================================================================
gabomdq@9023
    46
 Building an app
gabomdq@9023
    47
================================================================================
gabomdq@9023
    48
gabomdq@9023
    49
For simple projects you can use the script located at build-scripts/androidbuild.sh
gabomdq@9023
    50
gabomdq@9023
    51
There's two ways of using it:
gabomdq@9023
    52
philipp@9066
    53
    androidbuild.sh com.yourcompany.yourapp < sources.list
philipp@9066
    54
    androidbuild.sh com.yourcompany.yourapp source1.c source2.c ...sourceN.c
gabomdq@9023
    55
gabomdq@9023
    56
sources.list should be a text file with a source file name in each line
gabomdq@9023
    57
Filenames should be specified relative to the current directory, for example if
gabomdq@9023
    58
you are in the build-scripts directory and want to create the testgles.c test, you'll
gabomdq@9023
    59
run:
philipp@9066
    60
philipp@9066
    61
    ./androidbuild.sh org.libsdl.testgles ../test/testgles.c
gabomdq@9023
    62
gabomdq@9023
    63
One limitation of this script is that all sources provided will be aggregated into
gabomdq@9023
    64
a single directory, thus all your source files should have a unique name.
gabomdq@9023
    65
gabomdq@9023
    66
Once the project is complete the script will tell you where the debug APK is located.
gabomdq@9023
    67
If you want to create a signed release APK, you can use the project created by this
gabomdq@9023
    68
utility to generate it.
gabomdq@9023
    69
gabomdq@9023
    70
Finally, a word of caution: re running androidbuild.sh wipes any changes you may have
gabomdq@9023
    71
done in the build directory for the app!
gabomdq@9023
    72
gabomdq@9023
    73
gabomdq@9023
    74
For more complex projects, follow these instructions:
gabomdq@9023
    75
    
gabomdq@9023
    76
1. Copy the android-project directory wherever you want to keep your projects
gabomdq@9023
    77
   and rename it to the name of your project.
slouken@11647
    78
2. Move or symlink this SDL directory into the "<project>/app/jni" directory
slouken@11647
    79
3. Edit "<project>/app/jni/src/Android.mk" to include your source files
gabomdq@9023
    80
4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
gabomdq@9023
    81
slouken@11647
    82
If you want to use Android Studio (recommended), skip to the Android Studio section below.
gabomdq@9023
    83
slouken@11647
    84
5. Run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
gabomdq@9023
    85
gabomdq@9023
    86
Here's an explanation of the files in the Android project, so you can customize them:
gabomdq@9023
    87
slouken@11647
    88
    android-project/app
slouken@11647
    89
        build.gradle            - build info including the application version and SDK
slouken@11647
    90
        src/main/AndroidManifest.xml	- package manifest. Among others, it contains the class name
philipp@9055
    91
        			  of the main Activity and the package name of the application.
philipp@9055
    92
        jni/			- directory holding native code
slouken@11647
    93
        jni/Application.mk	- Application JNI settings, including target platform and STL library
slouken@11647
    94
        jni/Android.mk		- Android makefile that can call recursively the Android.mk files in all subdirectories
philipp@9055
    95
        jni/SDL/		- (symlink to) directory holding the SDL library files
philipp@9055
    96
        jni/SDL/Android.mk	- Android makefile for creating the SDL shared library
philipp@9055
    97
        jni/src/		- directory holding your C/C++ source
slouken@11647
    98
        jni/src/Android.mk	- Android makefile that you should customize to include your source code and any library references
slouken@11647
    99
        src/main/assets/	- directory holding asset files for your application
slouken@11647
   100
        src/main/res/		- directory holding resources for your application
slouken@11647
   101
        src/main/res/mipmap-*	- directories holding icons for different phone hardware
slouken@11647
   102
        src/main/res/values/strings.xml	- strings used in your application, including the application name
slouken@11647
   103
        src/main/java/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding to SDL. Be very careful changing this, as the SDL library relies on this implementation. You should instead subclass this for your application.
gabomdq@9023
   104
gabomdq@9023
   105
gabomdq@9023
   106
================================================================================
gabomdq@9023
   107
 Customizing your application name
gabomdq@9023
   108
================================================================================
gabomdq@9023
   109
gabomdq@9023
   110
To customize your application name, edit AndroidManifest.xml and replace
gabomdq@9023
   111
"org.libsdl.app" with an identifier for your product package.
gabomdq@9023
   112
gabomdq@9023
   113
Then create a Java class extending SDLActivity and place it in a directory
gabomdq@9023
   114
under src matching your package, e.g.
philipp@9055
   115
philipp@9066
   116
    src/com/gamemaker/game/MyGame.java
gabomdq@9023
   117
gabomdq@9023
   118
Here's an example of a minimal class file:
gabomdq@9023
   119
philipp@9050
   120
    --- MyGame.java --------------------------
philipp@9050
   121
    package com.gamemaker.game;
philipp@9050
   122
    
philipp@9050
   123
    import org.libsdl.app.SDLActivity; 
philipp@9050
   124
    
philipp@9065
   125
    /**
philipp@9050
   126
     * A sample wrapper class that just calls SDLActivity 
philipp@9050
   127
     */ 
philipp@9050
   128
    
philipp@9050
   129
    public class MyGame extends SDLActivity { }
philipp@9050
   130
    
philipp@9050
   131
    ------------------------------------------
gabomdq@9023
   132
gabomdq@9023
   133
Then replace "SDLActivity" in AndroidManifest.xml with the name of your
gabomdq@9023
   134
class, .e.g. "MyGame"
gabomdq@9023
   135
slouken@11647
   136
gabomdq@9023
   137
================================================================================
gabomdq@9023
   138
 Customizing your application icon
gabomdq@9023
   139
================================================================================
gabomdq@9023
   140
gabomdq@9023
   141
Conceptually changing your icon is just replacing the "ic_launcher.png" files in
slouken@11647
   142
the drawable directories under the res directory. There are several directories
slouken@11647
   143
for different screen sizes.
gabomdq@9023
   144
gabomdq@9023
   145
gabomdq@9023
   146
================================================================================
gabomdq@9023
   147
 Loading assets
gabomdq@9023
   148
================================================================================
gabomdq@9023
   149
slouken@11647
   150
Any files you put in the "app/src/main/assets" directory of your project
slouken@11647
   151
directory will get bundled into the application package and you can load
slouken@11647
   152
them using the standard functions in SDL_rwops.h.
gabomdq@9023
   153
gabomdq@9023
   154
There are also a few Android specific functions that allow you to get other
gabomdq@9023
   155
useful paths for saving and loading data:
philipp@9066
   156
* SDL_AndroidGetInternalStoragePath()
philipp@9066
   157
* SDL_AndroidGetExternalStorageState()
philipp@9066
   158
* SDL_AndroidGetExternalStoragePath()
gabomdq@9023
   159
gabomdq@9023
   160
See SDL_system.h for more details on these functions.
gabomdq@9023
   161
gabomdq@9023
   162
The asset packaging system will, by default, compress certain file extensions.
gabomdq@9023
   163
SDL includes two asset file access mechanisms, the preferred one is the so
gabomdq@9023
   164
called "File Descriptor" method, which is faster and doesn't involve the Dalvik
gabomdq@9023
   165
GC, but given this method does not work on compressed assets, there is also the
gabomdq@9023
   166
"Input Stream" method, which is automatically used as a fall back by SDL. You
gabomdq@9023
   167
may want to keep this fact in mind when building your APK, specially when large
gabomdq@9023
   168
files are involved.
gabomdq@9023
   169
For more information on which extensions get compressed by default and how to
gabomdq@9023
   170
disable this behaviour, see for example:
gabomdq@9023
   171
    
gabomdq@9023
   172
http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/
gabomdq@9023
   173
slouken@11647
   174
gabomdq@9023
   175
================================================================================
gabomdq@9023
   176
 Pause / Resume behaviour
gabomdq@9023
   177
================================================================================
gabomdq@9023
   178
gabomdq@9023
   179
If SDL is compiled with SDL_ANDROID_BLOCK_ON_PAUSE defined (the default),
gabomdq@9023
   180
the event loop will block itself when the app is paused (ie, when the user
gabomdq@9023
   181
returns to the main Android dashboard). Blocking is better in terms of battery
gabomdq@9023
   182
use, and it allows your app to spring back to life instantaneously after resume
gabomdq@9023
   183
(versus polling for a resume message).
gabomdq@9023
   184
gabomdq@9023
   185
Upon resume, SDL will attempt to restore the GL context automatically.
gabomdq@9023
   186
In modern devices (Android 3.0 and up) this will most likely succeed and your
gabomdq@9023
   187
app can continue to operate as it was.
gabomdq@9023
   188
gabomdq@9023
   189
However, there's a chance (on older hardware, or on systems under heavy load),
gabomdq@9023
   190
where the GL context can not be restored. In that case you have to listen for
gabomdq@9023
   191
a specific message, (which is not yet implemented!) and restore your textures
gabomdq@9023
   192
manually or quit the app (which is actually the kind of behaviour you'll see
gabomdq@9023
   193
under iOS, if the OS can not restore your GL context it will just kill your app)
gabomdq@9023
   194
slouken@11647
   195
gabomdq@9023
   196
================================================================================
gabomdq@9023
   197
 Threads and the Java VM
gabomdq@9023
   198
================================================================================
gabomdq@9023
   199
gabomdq@9023
   200
For a quick tour on how Linux native threads interoperate with the Java VM, take
icculus@10891
   201
a look here: https://developer.android.com/guide/practices/jni.html
philipp@9066
   202
gabomdq@9023
   203
If you want to use threads in your SDL app, it's strongly recommended that you
gabomdq@9023
   204
do so by creating them using SDL functions. This way, the required attach/detach
gabomdq@9023
   205
handling is managed by SDL automagically. If you have threads created by other
gabomdq@9023
   206
means and they make calls to SDL functions, make sure that you call
philipp@9065
   207
Android_JNI_SetupThread() before doing anything else otherwise SDL will attach
gabomdq@9023
   208
your thread automatically anyway (when you make an SDL call), but it'll never
gabomdq@9023
   209
detach it.
gabomdq@9023
   210
slouken@11647
   211
gabomdq@9023
   212
================================================================================
gabomdq@9023
   213
 Using STL
gabomdq@9023
   214
================================================================================
gabomdq@9023
   215
gabomdq@9023
   216
You can use STL in your project by creating an Application.mk file in the jni
gabomdq@9023
   217
folder and adding the following line:
philipp@9066
   218
philipp@9066
   219
    APP_STL := stlport_static
gabomdq@9023
   220
gabomdq@9023
   221
For more information check out CPLUSPLUS-SUPPORT.html in the NDK documentation.
gabomdq@9023
   222
slouken@11647
   223
gabomdq@9023
   224
================================================================================
gabomdq@9023
   225
 Additional documentation
gabomdq@9023
   226
================================================================================
gabomdq@9023
   227
gabomdq@9023
   228
The documentation in the NDK docs directory is very helpful in understanding the
gabomdq@9023
   229
build process and how to work with native code on the Android platform.
gabomdq@9023
   230
gabomdq@9023
   231
The best place to start is with docs/OVERVIEW.TXT
gabomdq@9023
   232
gabomdq@9023
   233
gabomdq@9023
   234
================================================================================
slouken@11647
   235
 Using Android Studio
gabomdq@9023
   236
================================================================================
gabomdq@9023
   237
slouken@11647
   238
You can open your project directory with Android Studio and run it normally.
gabomdq@9023
   239
gabomdq@9023
   240
gabomdq@9023
   241
================================================================================
gabomdq@9023
   242
 Using the emulator
gabomdq@9023
   243
================================================================================
gabomdq@9023
   244
gabomdq@9023
   245
There are some good tips and tricks for getting the most out of the
icculus@10891
   246
emulator here: https://developer.android.com/tools/devices/emulator.html
gabomdq@9023
   247
gabomdq@9023
   248
Especially useful is the info on setting up OpenGL ES 2.0 emulation.
gabomdq@9023
   249
gabomdq@9023
   250
Notice that this software emulator is incredibly slow and needs a lot of disk space.
gabomdq@9023
   251
Using a real device works better.
gabomdq@9023
   252
slouken@11647
   253
gabomdq@9023
   254
================================================================================
gabomdq@9023
   255
 Troubleshooting
gabomdq@9023
   256
================================================================================
gabomdq@9023
   257
gabomdq@9023
   258
You can see if adb can see any devices with the following command:
philipp@9055
   259
philipp@9066
   260
    adb devices
gabomdq@9023
   261
gabomdq@9023
   262
You can see the output of log messages on the default device with:
philipp@9055
   263
philipp@9066
   264
    adb logcat
gabomdq@9023
   265
gabomdq@9023
   266
You can push files to the device with:
philipp@9055
   267
philipp@9066
   268
    adb push local_file remote_path_and_file
gabomdq@9023
   269
gabomdq@9023
   270
You can push files to the SD Card at /sdcard, for example:
philipp@9055
   271
philipp@9066
   272
    adb push moose.dat /sdcard/moose.dat
gabomdq@9023
   273
gabomdq@9023
   274
You can see the files on the SD card with a shell command:
philipp@9055
   275
philipp@9066
   276
    adb shell ls /sdcard/
gabomdq@9023
   277
gabomdq@9023
   278
You can start a command shell on the default device with:
philipp@9055
   279
philipp@9066
   280
    adb shell
gabomdq@9023
   281
gabomdq@9023
   282
You can remove the library files of your project (and not the SDL lib files) with:
philipp@9055
   283
philipp@9066
   284
    ndk-build clean
gabomdq@9023
   285
gabomdq@9023
   286
You can do a build with the following command:
philipp@9055
   287
philipp@9066
   288
    ndk-build
gabomdq@9023
   289
gabomdq@9023
   290
You can see the complete command line that ndk-build is using by passing V=1 on the command line:
philipp@9055
   291
philipp@9066
   292
    ndk-build V=1
gabomdq@9023
   293
gabomdq@9023
   294
If your application crashes in native code, you can use addr2line to convert the
gabomdq@9023
   295
addresses in the stack trace to lines in your code.
gabomdq@9023
   296
gabomdq@9023
   297
For example, if your crash looks like this:
philipp@9050
   298
philipp@9050
   299
    I/DEBUG   (   31): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 400085d0
philipp@9050
   300
    I/DEBUG   (   31):  r0 00000000  r1 00001000  r2 00000003  r3 400085d4
philipp@9050
   301
    I/DEBUG   (   31):  r4 400085d0  r5 40008000  r6 afd41504  r7 436c6a7c
philipp@9050
   302
    I/DEBUG   (   31):  r8 436c6b30  r9 435c6fb0  10 435c6f9c  fp 4168d82c
philipp@9050
   303
    I/DEBUG   (   31):  ip 8346aff0  sp 436c6a60  lr afd1c8ff  pc afd1c902  cpsr 60000030
philipp@9050
   304
    I/DEBUG   (   31):          #00  pc 0001c902  /system/lib/libc.so
philipp@9050
   305
    I/DEBUG   (   31):          #01  pc 0001ccf6  /system/lib/libc.so
philipp@9050
   306
    I/DEBUG   (   31):          #02  pc 000014bc  /data/data/org.libsdl.app/lib/libmain.so
philipp@9050
   307
    I/DEBUG   (   31):          #03  pc 00001506  /data/data/org.libsdl.app/lib/libmain.so
gabomdq@9023
   308
gabomdq@9023
   309
You can see that there's a crash in the C library being called from the main code.
gabomdq@9023
   310
I run addr2line with the debug version of my code:
philipp@9055
   311
philipp@9066
   312
    arm-eabi-addr2line -C -f -e obj/local/armeabi/libmain.so
philipp@9055
   313
gabomdq@9023
   314
and then paste in the number after "pc" in the call stack, from the line that I care about:
gabomdq@9023
   315
000014bc
gabomdq@9023
   316
gabomdq@9023
   317
I get output from addr2line showing that it's in the quit function, in testspriteminimal.c, on line 23.
gabomdq@9023
   318
gabomdq@9023
   319
You can add logging to your code to help show what's happening:
gabomdq@9023
   320
philipp@9055
   321
    #include <android/log.h>
philipp@9055
   322
    
philipp@9055
   323
    __android_log_print(ANDROID_LOG_INFO, "foo", "Something happened! x = %d", x);
gabomdq@9023
   324
gabomdq@9023
   325
If you need to build without optimization turned on, you can create a file called
gabomdq@9023
   326
"Application.mk" in the jni directory, with the following line in it:
philipp@9066
   327
philipp@9066
   328
    APP_OPTIM := debug
gabomdq@9023
   329
gabomdq@9023
   330
gabomdq@9023
   331
================================================================================
gabomdq@9023
   332
 Memory debugging
gabomdq@9023
   333
================================================================================
gabomdq@9023
   334
gabomdq@9023
   335
The best (and slowest) way to debug memory issues on Android is valgrind.
gabomdq@9023
   336
Valgrind has support for Android out of the box, just grab code using:
philipp@9055
   337
philipp@9066
   338
    svn co svn://svn.valgrind.org/valgrind/trunk valgrind
philipp@9055
   339
gabomdq@9023
   340
... and follow the instructions in the file README.android to build it.
gabomdq@9023
   341
gabomdq@9023
   342
One thing I needed to do on Mac OS X was change the path to the toolchain,
gabomdq@9023
   343
and add ranlib to the environment variables:
gabomdq@9023
   344
export RANLIB=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-ranlib
gabomdq@9023
   345
gabomdq@9023
   346
Once valgrind is built, you can create a wrapper script to launch your
gabomdq@9023
   347
application with it, changing org.libsdl.app to your package identifier:
philipp@9050
   348
philipp@9050
   349
    --- start_valgrind_app -------------------
philipp@9050
   350
    #!/system/bin/sh
philipp@9050
   351
    export TMPDIR=/data/data/org.libsdl.app
philipp@9050
   352
    exec /data/local/Inst/bin/valgrind --log-file=/sdcard/valgrind.log --error-limit=no $*
philipp@9050
   353
    ------------------------------------------
gabomdq@9023
   354
gabomdq@9023
   355
Then push it to the device:
philipp@9055
   356
philipp@9066
   357
    adb push start_valgrind_app /data/local
gabomdq@9023
   358
gabomdq@9023
   359
and make it executable:
philipp@9055
   360
philipp@9066
   361
    adb shell chmod 755 /data/local/start_valgrind_app
gabomdq@9023
   362
gabomdq@9023
   363
and tell Android to use the script to launch your application:
philipp@9055
   364
philipp@9066
   365
    adb shell setprop wrap.org.libsdl.app "logwrapper /data/local/start_valgrind_app"
gabomdq@9023
   366
gabomdq@9023
   367
If the setprop command says "could not set property", it's likely that
gabomdq@9023
   368
your package name is too long and you should make it shorter by changing
gabomdq@9023
   369
AndroidManifest.xml and the path to your class file in android-project/src
gabomdq@9023
   370
gabomdq@9023
   371
You can then launch your application normally and waaaaaaaiiittt for it.
gabomdq@9023
   372
You can monitor the startup process with the logcat command above, and
gabomdq@9023
   373
when it's done (or even while it's running) you can grab the valgrind
gabomdq@9023
   374
output file:
philipp@9055
   375
philipp@9066
   376
    adb pull /sdcard/valgrind.log
gabomdq@9023
   377
gabomdq@9023
   378
When you're done instrumenting with valgrind, you can disable the wrapper:
philipp@9055
   379
philipp@9066
   380
    adb shell setprop wrap.org.libsdl.app ""
gabomdq@9023
   381
slouken@11647
   382
gabomdq@9023
   383
================================================================================
slouken@10487
   384
 Graphics debugging
slouken@10487
   385
================================================================================
slouken@10487
   386
philipp@10543
   387
If you are developing on a compatible Tegra-based tablet, NVidia provides
slouken@11647
   388
Tegra Graphics Debugger at their website. Because SDL2 dynamically loads EGL
philipp@10543
   389
and GLES libraries, you must follow their instructions for installing the
slouken@11647
   390
interposer library on a rooted device. The non-rooted instructions are not
philipp@10543
   391
compatible with applications that use SDL2 for video.
slouken@10487
   392
slouken@10487
   393
The Tegra Graphics Debugger is available from NVidia here:
slouken@10487
   394
https://developer.nvidia.com/tegra-graphics-debugger
slouken@10487
   395
slouken@11647
   396
slouken@10487
   397
================================================================================
slouken@11649
   398
 Why is API level 14 the minimum required?
gabomdq@9023
   399
================================================================================
gabomdq@9023
   400
slouken@11649
   401
The latest NDK toolchain doesn't support targeting earlier than API level 14.
icculus@10891
   402
As of this writing, according to https://developer.android.com/about/dashboards/index.html
slouken@11649
   403
about 99% of the Android devices accessing Google Play support API level 14 or
slouken@11649
   404
higher (October 2017).
gabomdq@9023
   405
slouken@11647
   406
gabomdq@9023
   407
================================================================================
gabomdq@9023
   408
 A note regarding the use of the "dirty rectangles" rendering technique
gabomdq@9023
   409
================================================================================
gabomdq@9023
   410
gabomdq@9023
   411
If your app uses a variation of the "dirty rectangles" rendering technique,
gabomdq@9023
   412
where you only update a portion of the screen on each frame, you may notice a
gabomdq@9023
   413
variety of visual glitches on Android, that are not present on other platforms.
gabomdq@9023
   414
This is caused by SDL's use of EGL as the support system to handle OpenGL ES/ES2
gabomdq@9023
   415
contexts, in particular the use of the eglSwapBuffers function. As stated in the
gabomdq@9023
   416
documentation for the function "The contents of ancillary buffers are always 
gabomdq@9023
   417
undefined after calling eglSwapBuffers".
gabomdq@9023
   418
Setting the EGL_SWAP_BEHAVIOR attribute of the surface to EGL_BUFFER_PRESERVED
gabomdq@9023
   419
is not possible for SDL as it requires EGL 1.4, available only on the API level
gabomdq@9023
   420
17+, so the only workaround available on this platform is to redraw the entire
gabomdq@9023
   421
screen each frame.
gabomdq@9023
   422
gabomdq@9023
   423
Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html
gabomdq@9023
   424
slouken@11647
   425
gabomdq@9023
   426
================================================================================
gabomdq@9023
   427
 Known issues
gabomdq@9023
   428
================================================================================
gabomdq@9023
   429
gabomdq@9023
   430
- The number of buttons reported for each joystick is hardcoded to be 36, which
gabomdq@9023
   431
is the current maximum number of buttons Android can report.
gabomdq@9023
   432