SlideShare a Scribd company logo
AGDK tutorial
(Step by step)
Jungsoo Nam
2022/March/1st
Test environment and reference materials
● Android Studio and NDK version
○ Bumblebee 2021.1.1 Patch 1
○ NDK 23.1.7779620
● Rendering API
○ OpenGL (excludes Vulkan)
● Documentation
○ https://developer.android.com/games/agdk/integrate-game-activity
○ https://developer.android.com/ndk/guides
● Source code
○ https://github.com/namjungsoo/GameActivityTutorial
● Official source codes
○ https://android.googlesource.com/platform/frameworks/opt/gamesdk/
○ https://github.com/android/games-samples
○ https://github.com/android/ndk-samples/
What is AGDK?
Android Game Development Kit (AGDK), a full range of tools and libraries to help you develop, optimize, and deliver high
quality Android games.
AGDK features follow three key tenets:
● Code built for game development. All of our libraries have been built and tested with performance in mind
using C or C++ APIs.
● Reduce fragmentation. The AGDK tools and libraries work across many different Android versions. Most of
these features will work on almost any device in use today.
● Built by Android, for Android. Features will be enhanced by future Android platform updates, and the libraries
will provide backwards compatibility when possible.
C/C++ game libraries
AGDK will help you build and customize game engines by providing C game libraries that minimize the use of the Java
Programming language and JNI. This makes your games easier to build, debug, and maintain.
● Game Activity provides a foundation for C++ games to be built on. It provides C interfaces for all the Android
events that you'd expect, from screen rotation to app lifecycle. This way you can minimize the amount of
development time you spend in the Java language. Unlike Native Activity, Game Activity is compatible with
fragments and extendable, making it easier to integrate some of your favourite SDKs.
● Game Text input provides a stable way to use the software keyboard in C, that is officially supported and will
work across Android versions.
● Game Controller is a way to handle input from game controllers in C, to map their functions and to reconnect to
the device when necessary.
GameActivity vs NativeActivity
Unity3D 4.6 vs Unity 2020.3
● UnityPlayerNativeActivity / UnityPlayerActivity
What this presentation includes/excludes
● Includes
○ GameActivity
○ GameTextInput
○ GameTouchInput
○ Oboe
○ Games frame pacing
○ Android performance tuner
○ OpenGL ES rendering API
● Excludes
○ GameController
○ Android GPU Inspector (AGI) profiling
○ Android Game Development Extension for Visual Studio
○ Debugging Native Memory
○ GameMode API
○ Turnkey Game Engines
○ Vulkan rendering API
GameActivity offers
● Inherits from AppCompatActivity, allowing you to use Android Jetpack Architecture Components.
● Renders into a SurfaceView that allows you to interface with any other Android UI element.
● Handles Java activity events. This allows any Android UI element (such as a EditText, a WebView or an Ad) to be
integrated to your game via a C interface.
● Offers a C API similar to NativeActivity, and android_native_app_glue library.
New Project - Native C++
Project ‘GameActivityTutorial’ created
Setup a GameActivity 1/2 (Java/Kotlin)
Setup a GameActivity 2/2 (Native C++)
● CMakeLists.txt
● gradle.properties
● build.gradle (module)
Add metadata into
AndroidManifest.xml
● GameActivity.onCreate
Add some included source files
● game_activity_included.cpp / native_app_glue_included.c
● game_text_input_included.cpp
Implement android_main()
● android_main.cpp
Start implementing NativeEngine 1/2
● CMakeLists.txt
Start implementing NativeEngine 2/2
● NativeEngine.hpp/cpp
How android_main() can be called? 1/4
● GameActivity.class / GameActivity.cpp
○ String libname = “main”;
○ String funcname = "GameActivity_onCreate";
How android_main() can be called? 2/4
● GameActivity.cpp
How android_main() can be called? 3/4
● GameActivity.h / android_native_app_glue.c
How android_main() can be called? 4/4
● android_native_app_glue.c
Render the first frame 1/4
● handle appCmd
Command Value Command Value
APP_CMD_INIT_WINDOW mHasWindow
= true
APP_CMD_TERM_WINDOW mHasWindow
= false
APP_CMD_GAINED_FOCUS mHasFocus =
true
APP_CMD_LOST_FOCUS mHasFocus =
false
APP_CMD_START mIsVisible =
true
APP_CMD_STOP mIsVisible =
false
Render the first frame 2/4
● PrepareToRender()
Render the first frame 3/4
● InitDisplay/Surface/Context
● ConfigureOpenGL/HandleEglError
Render the first frame 4/4
● DO NOT call setContentView
○ When called, the appstate does not transit to
APP_CMD_INIT_WINDOW.
Handle touch input 1/2
The official sample code lacks explanation.
Handle touch input 2/2
Handle text input 1/2
Handle text input 2/2
‘구글코리아' means ‘Google Korea’
Korean compositing is also OK.
Output audio - Oboe
Use Oboe to gain the following benefits:
● Achieve the lowest latency. Oboe helps your application achieve the lowest-possible audio latency for a given device
and Android version combination.
● Use the best available native library. On devices running Android API 8.1 (API level 27) and higher, Oboe uses
AAudio. For devices running lower versions, Oboe uses OpenSL ES.
● Avoid audio bugs. Oboe includes workarounds for some known audio issues that manifest on specific devices or
versions of Android. Using Oboe helps your application avoid these issues without having to implement or test your
own solutions.
Output audio - Play sine wave
Official README has some bugs.
I fixed and pushed a PR:
https://github.com/google/oboe/pull/1495
Games-frame-pacing
Non-optimal solutions
Submit frames as quickly as the rendering API allows
Too quick frames cause buffer stuffing (no more room in queue, game loop is blocked by API)
Use android choreographer
API 16, C++ API 24, depends on device, buffer stuffing for long frames
Advantages of the Frame Pacing library
Make sure frames are Presented at the proper time and sync fences to avoid buffer stuffing. The library uses the NDK Choreographer if it is available and falls back
to the Java Choreographer if it is not.
The library handles multiple refresh rates if they are supported by the device.
Games-frame-pacing
Short game frames lead to stuttering -> EGL_ANDROID_presentation_time
Long frames lead to stuttering and latency -> EGL_KHR_fence_sync
Check EGL extensions
Use SwappyGL 1/3
CMakeLists.txt
build.gradle (module)
Use SwappyGL 2/3
● native_engine.hpp/cpp
Use SwappyGL 3/3
● native_engine.hpp/cpp
Android performance tuner
Why use the Android Performance Tuner?
Android Performance Tuner helps you to measure and optimize your game's frame rate stability and graphical fidelity across many Android devices
at scale, enabling you to deliver the best possible experience to each of your users. The Android Performance Tuner library, also known as Tuning
Fork, records and aggregates live frame time information from your game, alongside your own game annotations and fidelity parameters, and
uploads this data to the Play Console. This unlocks a new suite of metrics and insights in Android vitals.
How does it work?
Android Performance Tuner works with Android vitals.
● Android Performance Tuner records and aggregates live frame time and loading information from your game or app, alongside
game annotations and fidelity parameters that you provide.
● When you publish a version of your game or app with Android Performance Tuner, this performance data is uploaded to Google
Play and unlocks new performance insights in Android vitals.
To get these performance insights, you must integrate Android Performance Tuner into your game or app and then publish it on
Google Play:
TuningFork settings 1/2
TuningFork settings 2/2
Add TuningManager.hpp/cpp
Add TuningManager.hpp/cpp
Choreographer compile problem
android/choreographer.h
SwappyTracer
Apply TuningManager
Thank you
● Q&A

More Related Content

PPTX
Android - Application Framework
PDF
Docker architecture-04-1
PPTX
Automation Testing by Selenium Web Driver
PPTX
.Net Core
PPTX
Nightwatch JS for End to End Tests
PPTX
Android jetpack compose | Declarative UI
PPTX
Introduction to Flutter.pptx
PPT
Selenium ppt
Android - Application Framework
Docker architecture-04-1
Automation Testing by Selenium Web Driver
.Net Core
Nightwatch JS for End to End Tests
Android jetpack compose | Declarative UI
Introduction to Flutter.pptx
Selenium ppt

What's hot (20)

PDF
Gitlab ci-cd
PDF
svn 능력자를 위한 git 개념 가이드
PPTX
Maven
PDF
Room 1 - 5 - Thủy Đặng - Load balancing k8s services on baremetal with Cilium...
PDF
Robot Framework with Python | Edureka
PPTX
Selenium introduction
PDF
Mockito a simple, intuitive mocking framework
PDF
Understanding the Android System Server
PPTX
PDF
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
PDF
CMake - Introduction and best practices
PDF
Flutter state management from zero to hero
DOCX
FINAL APP DEVELOPMENT REPORT -DONE
PDF
[OpenStack 하반기 스터디] Docker를 이용한 OpenStack 가상화
PDF
Android Treble: Blessing or Trouble?
PPTX
.Net framework
PDF
GITS Class #16: CI/CD (Continuous Integration & Continuous Deployment) with G...
PDF
InjectionIII의 Hot Reload를 이용하여 앱 개발을 좀 더 편하게 하기.pdf
PDF
도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!
PDF
BKK16-315 Graphics Stack Update
Gitlab ci-cd
svn 능력자를 위한 git 개념 가이드
Maven
Room 1 - 5 - Thủy Đặng - Load balancing k8s services on baremetal with Cilium...
Robot Framework with Python | Edureka
Selenium introduction
Mockito a simple, intuitive mocking framework
Understanding the Android System Server
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
CMake - Introduction and best practices
Flutter state management from zero to hero
FINAL APP DEVELOPMENT REPORT -DONE
[OpenStack 하반기 스터디] Docker를 이용한 OpenStack 가상화
Android Treble: Blessing or Trouble?
.Net framework
GITS Class #16: CI/CD (Continuous Integration & Continuous Deployment) with G...
InjectionIII의 Hot Reload를 이용하여 앱 개발을 좀 더 편하게 하기.pdf
도커 무작정 따라하기: 도커가 처음인 사람도 60분이면 웹 서버를 올릴 수 있습니다!
BKK16-315 Graphics Stack Update
Ad

Similar to AGDK tutorial step by step (20)

PDF
[Gstar 2013] Unity Security
PDF
Inside Android's UI
PDF
Inside Android's UI / ABS 2013
PDF
LAS16-201: ART JIT in Android N
PDF
Fight back android fragmentation
PDF
Debug, Analyze and Optimize Games with Intel Tools
PDF
Debug, Analyze and Optimize Games with Intel Tools - Matteo Valoriani - Codem...
PDF
Debug, Analyze and Optimize Games with Intel Tools - Matteo Valoriani - Codem...
PPTX
PPTX
Porting games from ps3 or web to shield and ouya [final]
PPTX
Android Lollipop: The developer's perspective
PDF
Media and entertainment workload comparison: HP Z8 vs. Apple Mac Pro
PDF
Game Programming I - Introduction
PDF
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
PDF
COMPUTER GRAPHICS PROJECT REPORT
PDF
OpenGL Introduction.
PDF
WT-4066, The Making of Turbulenz’ Polycraft WebGL Benchmark, by Ian Ballantyne
ODP
HTML5 Game Development frameworks overview
DOCX
Computer graphics workbook
PDF
Flowframes
[Gstar 2013] Unity Security
Inside Android's UI
Inside Android's UI / ABS 2013
LAS16-201: ART JIT in Android N
Fight back android fragmentation
Debug, Analyze and Optimize Games with Intel Tools
Debug, Analyze and Optimize Games with Intel Tools - Matteo Valoriani - Codem...
Debug, Analyze and Optimize Games with Intel Tools - Matteo Valoriani - Codem...
Porting games from ps3 or web to shield and ouya [final]
Android Lollipop: The developer's perspective
Media and entertainment workload comparison: HP Z8 vs. Apple Mac Pro
Game Programming I - Introduction
Android on Windows 11 - A Developer's Perspective (Windows Subsystem For Andr...
COMPUTER GRAPHICS PROJECT REPORT
OpenGL Introduction.
WT-4066, The Making of Turbulenz’ Polycraft WebGL Benchmark, by Ian Ballantyne
HTML5 Game Development frameworks overview
Computer graphics workbook
Flowframes
Ad

More from Jungsoo Nam (8)

PPT
NVIDIA CUDA
PPTX
Android Grabber Module Proposal
PPTX
Unity3D Audio Grabber design
PPTX
Android OpenGL ES Game ImageGrabber Final Report
PPTX
13th kandroid OpenGL and EGL
PPTX
Android RenderScript
PPTX
OpenGL ES EGL Spec&APIs
PPTX
OpenGL Shading Language
NVIDIA CUDA
Android Grabber Module Proposal
Unity3D Audio Grabber design
Android OpenGL ES Game ImageGrabber Final Report
13th kandroid OpenGL and EGL
Android RenderScript
OpenGL ES EGL Spec&APIs
OpenGL Shading Language

Recently uploaded (20)

PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
MYSQL Presentation for SQL database connectivity
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Empathic Computing: Creating Shared Understanding
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation theory and applications.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Modernizing your data center with Dell and AMD
PPTX
A Presentation on Artificial Intelligence
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Electronic commerce courselecture one. Pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
Network Security Unit 5.pdf for BCA BBA.
MYSQL Presentation for SQL database connectivity
NewMind AI Monthly Chronicles - July 2025
Empathic Computing: Creating Shared Understanding
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation theory and applications.pdf
20250228 LYD VKU AI Blended-Learning.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Building Integrated photovoltaic BIPV_UPV.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Modernizing your data center with Dell and AMD
A Presentation on Artificial Intelligence
Encapsulation_ Review paper, used for researhc scholars
Electronic commerce courselecture one. Pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
NewMind AI Weekly Chronicles - August'25 Week I

AGDK tutorial step by step

  • 1. AGDK tutorial (Step by step) Jungsoo Nam 2022/March/1st
  • 2. Test environment and reference materials ● Android Studio and NDK version ○ Bumblebee 2021.1.1 Patch 1 ○ NDK 23.1.7779620 ● Rendering API ○ OpenGL (excludes Vulkan) ● Documentation ○ https://developer.android.com/games/agdk/integrate-game-activity ○ https://developer.android.com/ndk/guides ● Source code ○ https://github.com/namjungsoo/GameActivityTutorial ● Official source codes ○ https://android.googlesource.com/platform/frameworks/opt/gamesdk/ ○ https://github.com/android/games-samples ○ https://github.com/android/ndk-samples/
  • 3. What is AGDK? Android Game Development Kit (AGDK), a full range of tools and libraries to help you develop, optimize, and deliver high quality Android games. AGDK features follow three key tenets: ● Code built for game development. All of our libraries have been built and tested with performance in mind using C or C++ APIs. ● Reduce fragmentation. The AGDK tools and libraries work across many different Android versions. Most of these features will work on almost any device in use today. ● Built by Android, for Android. Features will be enhanced by future Android platform updates, and the libraries will provide backwards compatibility when possible.
  • 4. C/C++ game libraries AGDK will help you build and customize game engines by providing C game libraries that minimize the use of the Java Programming language and JNI. This makes your games easier to build, debug, and maintain. ● Game Activity provides a foundation for C++ games to be built on. It provides C interfaces for all the Android events that you'd expect, from screen rotation to app lifecycle. This way you can minimize the amount of development time you spend in the Java language. Unlike Native Activity, Game Activity is compatible with fragments and extendable, making it easier to integrate some of your favourite SDKs. ● Game Text input provides a stable way to use the software keyboard in C, that is officially supported and will work across Android versions. ● Game Controller is a way to handle input from game controllers in C, to map their functions and to reconnect to the device when necessary.
  • 6. Unity3D 4.6 vs Unity 2020.3 ● UnityPlayerNativeActivity / UnityPlayerActivity
  • 7. What this presentation includes/excludes ● Includes ○ GameActivity ○ GameTextInput ○ GameTouchInput ○ Oboe ○ Games frame pacing ○ Android performance tuner ○ OpenGL ES rendering API ● Excludes ○ GameController ○ Android GPU Inspector (AGI) profiling ○ Android Game Development Extension for Visual Studio ○ Debugging Native Memory ○ GameMode API ○ Turnkey Game Engines ○ Vulkan rendering API
  • 8. GameActivity offers ● Inherits from AppCompatActivity, allowing you to use Android Jetpack Architecture Components. ● Renders into a SurfaceView that allows you to interface with any other Android UI element. ● Handles Java activity events. This allows any Android UI element (such as a EditText, a WebView or an Ad) to be integrated to your game via a C interface. ● Offers a C API similar to NativeActivity, and android_native_app_glue library.
  • 9. New Project - Native C++
  • 11. Setup a GameActivity 1/2 (Java/Kotlin)
  • 12. Setup a GameActivity 2/2 (Native C++) ● CMakeLists.txt ● gradle.properties ● build.gradle (module)
  • 14. Add some included source files ● game_activity_included.cpp / native_app_glue_included.c ● game_text_input_included.cpp
  • 16. Start implementing NativeEngine 1/2 ● CMakeLists.txt
  • 17. Start implementing NativeEngine 2/2 ● NativeEngine.hpp/cpp
  • 18. How android_main() can be called? 1/4 ● GameActivity.class / GameActivity.cpp ○ String libname = “main”; ○ String funcname = "GameActivity_onCreate";
  • 19. How android_main() can be called? 2/4 ● GameActivity.cpp
  • 20. How android_main() can be called? 3/4 ● GameActivity.h / android_native_app_glue.c
  • 21. How android_main() can be called? 4/4 ● android_native_app_glue.c
  • 22. Render the first frame 1/4 ● handle appCmd Command Value Command Value APP_CMD_INIT_WINDOW mHasWindow = true APP_CMD_TERM_WINDOW mHasWindow = false APP_CMD_GAINED_FOCUS mHasFocus = true APP_CMD_LOST_FOCUS mHasFocus = false APP_CMD_START mIsVisible = true APP_CMD_STOP mIsVisible = false
  • 23. Render the first frame 2/4 ● PrepareToRender()
  • 24. Render the first frame 3/4 ● InitDisplay/Surface/Context ● ConfigureOpenGL/HandleEglError
  • 25. Render the first frame 4/4 ● DO NOT call setContentView ○ When called, the appstate does not transit to APP_CMD_INIT_WINDOW.
  • 26. Handle touch input 1/2 The official sample code lacks explanation.
  • 29. Handle text input 2/2 ‘구글코리아' means ‘Google Korea’ Korean compositing is also OK.
  • 30. Output audio - Oboe Use Oboe to gain the following benefits: ● Achieve the lowest latency. Oboe helps your application achieve the lowest-possible audio latency for a given device and Android version combination. ● Use the best available native library. On devices running Android API 8.1 (API level 27) and higher, Oboe uses AAudio. For devices running lower versions, Oboe uses OpenSL ES. ● Avoid audio bugs. Oboe includes workarounds for some known audio issues that manifest on specific devices or versions of Android. Using Oboe helps your application avoid these issues without having to implement or test your own solutions.
  • 31. Output audio - Play sine wave Official README has some bugs. I fixed and pushed a PR: https://github.com/google/oboe/pull/1495
  • 32. Games-frame-pacing Non-optimal solutions Submit frames as quickly as the rendering API allows Too quick frames cause buffer stuffing (no more room in queue, game loop is blocked by API) Use android choreographer API 16, C++ API 24, depends on device, buffer stuffing for long frames Advantages of the Frame Pacing library Make sure frames are Presented at the proper time and sync fences to avoid buffer stuffing. The library uses the NDK Choreographer if it is available and falls back to the Java Choreographer if it is not. The library handles multiple refresh rates if they are supported by the device.
  • 33. Games-frame-pacing Short game frames lead to stuttering -> EGL_ANDROID_presentation_time Long frames lead to stuttering and latency -> EGL_KHR_fence_sync
  • 36. Use SwappyGL 2/3 ● native_engine.hpp/cpp
  • 37. Use SwappyGL 3/3 ● native_engine.hpp/cpp
  • 38. Android performance tuner Why use the Android Performance Tuner? Android Performance Tuner helps you to measure and optimize your game's frame rate stability and graphical fidelity across many Android devices at scale, enabling you to deliver the best possible experience to each of your users. The Android Performance Tuner library, also known as Tuning Fork, records and aggregates live frame time information from your game, alongside your own game annotations and fidelity parameters, and uploads this data to the Play Console. This unlocks a new suite of metrics and insights in Android vitals. How does it work? Android Performance Tuner works with Android vitals. ● Android Performance Tuner records and aggregates live frame time and loading information from your game or app, alongside game annotations and fidelity parameters that you provide. ● When you publish a version of your game or app with Android Performance Tuner, this performance data is uploaded to Google Play and unlocks new performance insights in Android vitals. To get these performance insights, you must integrate Android Performance Tuner into your game or app and then publish it on Google Play:

Editor's Notes

  • #2: Hello, everyone. Nice to meet you all and thank you for being here. And I am so happy for presenting this topic because I love this topic so much. My name is Jungsoo Nam. I’m based in South Korea and a former game engine engineer and now an android engineer. Today, the topic of my presentation is AGDK tutorial step by step.
  • #3: Here you can see the test environment and reference materials that used in my presentation. There are many useful source codes and documentations in the official Google Android developer website and Github repositories. Basically, AGDK is also developed using NDK, so it is important to familiarize yourself with previous NDK materials. I think you are all familiar with using NDK.
  • #4: I watched the AGDK release on July 13th, 2021, in real-time on YouTube. It was a library I was personally very excited about, and I look forward to applying it to my work. Well, What is AGDK? Android Game Development Kit (AGDK), a full range of tools and libraries to help you develop, optimize, and deliver high quality Android games. AGDK features follow three key tenets. C/C++ APIs: Game developers use C or C++ for high performance. Reduce fragmentation: Android engineers are always solving fragmentation problems. Built by Android, for Android: Also backward compatibility is important. Now in the metaverse era, not only games but also AR/VR so called XR app uses graphical features, so the app needs to cowork between general UI and graphics screen. For instance, an app using Unity as a library. It is mixed by normal Activities and Unity Activities.
  • #5: Unlike Native Activity, Game Activity is compatible with fragments and extendable, making it easier to integrate some of your favorite SDKs. Because GameActivity inherits from AppCompatActivity. AppCompatActivity inherits from FragmentActivity which provides Fragments. FragmentActivity inherits from ComponentActivity which provides Lifecycle management. GameTextInput, In my experience in the past, it relied on java calls to show/hide the soft keyboard, and it was very inconvenient to manage Korean composition in java. Connecting gamer’s game controller is very important. For example, I’m currently using the Xbox Controller through Bluetooth on my gaming laptop, and it often disconnects itself and automatic reconnection is not supported, this is so inconvenient.
  • #6: Let’s compare GameActivity (left) with NativeActivity (right) NativeActivity inherits from Activity, and implements SurfaceHolder.Callback2, and InputQueue.Callback. On the other hand, GameActivity inherits from AppCompatActivity, and implements SurfaceHolder.Callback2, gametextinput.Listener. The major differences are inherited from Activity vs AppCompatActivity, and GameActivity supports GameTextInput. NativeActivity has its own InputMethodManager instance in java side.
  • #7: Another one, let's compare Unity3D 4.6 and Unity 2020.3 the latest LTS version. Unity 4.6 used to use UnityPlayerNativeActivity, on the other hand, Unity 2020.3 uses UnityPlayerActivity. The latest version no more uses NativeActivity and added implementing lifecycle callback interface. In the long run, in my opinion, Unity will adopt using GameActivity for improving their performance.
  • #8: I will cover GameActivity, GameTextInput, GameTouchInput, Oboe, Game frame pacing, Android performance tuner, and OpenGL ES API in following slides. I won’t cover the excludes, but that doesn't mean those are not important. - Excluded things are probably more important for supporting our customers the game companies. - Vulkan's adoption is getting broader. - GPU profiling is important traditionally. - Still most game developers are using Visual Studio. - Almost no mobile games are possible without Unity and Unreal Engine.
  • #9: Let me check about GameActivity offers again. Allowing to use Android Jetpack Architecture Components is most important. Other offers are similar to NativeActivity.
  • #10: Ok, so launch our Android Studio and Goto menu choose ‘File > New > New Project’. Choose ‘Native C++’ project type in ‘Phone and Tablet tab’. Input project name as ‘GameActivityTutorial’.
  • #11: This is the initial project screen. Since we selected ‘Native C++’, you can see the cpp folder on the left side, CMakeLists.txt was added, and native-related settings were set in gradle.
  • #12: Now let's set up the GameActivity. 1. Add implementation games-activity:1.1.0-rc01 2. Change AppCompatActivity to GameActivity.
  • #13: 3. Add game-activity to find_package in CMakeLists.txt 4. Add game-activity::game-activity to target_link_libraries 5. Set android.prefabVersion as 1.1.2 in gradle.properties 6. Set buildFeatures.prefab = true in build.gradle (module level) Prefab includes the headers and libraries of the native dependency.
  • #14: More, add android.app.lib_name=”gameactivitytutorial” as AndroidManifest’s MainActivity meta-data This was the same way in the NDK. In GameActivity.onCreate, load library by given library name. Library loading is done dynamically by dlopen and dlsym in loadNativeCode_native.
  • #15: Also, we need to include some source files as headers. Including files must be c or cpp source file and declared in CMakeList.txt for compile. We declare these later.
  • #16: Next, we implement the android_main function in android_main.cpp If extension is cpp, we have to use extern “C” for C compatibility. (For the detail, as you know, cpp does mangle names, we prevent it.)
  • #17: Open CMakeLists.txt again, we add our own c and cpp source files in here add_library. Plus, android, EGL, and GLESv3 libraries to target_link_libraries section. Android is android specific library, EGL is for EGL, GLESv3 for OpenGL ES library.
  • #18: Now, let's move on to implementing NativeEngine. 1. Add NativeEngine.hpp/cpp files. 2. Add Constructor and Destructor, GameLoop, IsAnimating, and DoFrame. 3. Add android_app app pointer as a private member variable. 4. In GameLoop function, set this pointer to mApp’s userData, and loop a while block. When calling ALooper_pollAll, -1 is infinite. If not animating, we will block forever waiting for events. If animating, we loop until all events are read, then continue to draw the next frame of animation.
  • #19: At this moment, let's find out how android_main function can be called. I know you've already known about this. Anyway, for reminding. In GameActivity.java, onCreate method calls loadNativeCode method, In JNI side, Java_com_google_androidgamessdk_GameActivity_loadNativeCode matches GameActivity.loadNativeCode. libname “main” is replaced with “gameactivitytutorial”, but funcname “GameActivity_onCreate” does not change.
  • #20: In loadNativeCode_native function, we bind GameActivity_onCreate function and create a NativeCode instance for storing native states. First parameter is library handle, second one is GameActivity_onCreate function’s pointer.
  • #21: GameActivity_onCreate is declared in android_native_app_glue.c But we included android_native_app_glue.c into gameactivitytutorial library. So we load GameActivity_onCreate dynamically through dlopen and dlsym. (I mentioned this in the previous page) The GameActivity pointer activity is a NativeCode instance.
  • #22: Calling android_app_create by GameActivity_onCreate. (in the previous page) Then it creates a new thread with android_app_entry as a thread function. android_app_entry then runs android_app_main function. The reason why separating threads is for avoiding blocking the main thread.
  • #23: So, let’s get first frame of our game. Register _handle_cmd_proxy callback function to mApp->onAppCmd In _handle_cmd_proxy, type cast app->userData to NativeEngine pointer, then call HandleCommand NativeEngine’s HandleCommand handles enum NativeAppGlueAppCmd declared in android_native_app_glue.h
  • #24: 2nd, we add PrepareToRender function. It is called by DoFrame. PrepareToRender checks whether mEglDisplay, mEglSurface, mEglContext is set or not.
  • #25: 3rd, we add InitDisplay, InitSurface, InitContext These are ordinary EGL initialization. In ConfigureOpenGL, we just set clear color and enable depth test and clear back buffer.
  • #26: Finally, Remove setContentView calling in Java (kotlin) side. When we set content view, app state does not transit to APP_CMD_INIT_WINDOW, then we get always Init surface failed.
  • #27: We need to handle touch now for the next step. Let’s add HandleGameActivityInput to NativeEngine and call it from GameLoop. Store surface’s width and height for determining touch area. When motionEvents exist, call _cook_game_activity_motion_event with motionEvent, surfWidth, suftHeight.
  • #28: _cook_game_activity_motion_event function converts raw event to cooked event and passes the cooked event to the callback function. Cooked events are more simple. Logcat in the bottom shows callbacked touch events.
  • #29: Another AGDK component, the GameTextInput. Let’s try to add it. 1. make NativeEngine as a Singleton for C callback. 2. add GameTextInputState as a member variable. 3. check mApp->textInputState in GameLoop.
  • #30: 4. add OnTextInput. In OnTextInput, copy GameTextInputState callbacked by getTextInputState to NativeEngine local. 5. for testing, add UpdateInputMode function for toggling show/hide soft input keyboard. Now that I think about it, the name ToggleInputMode seems better than UpdateInputMode. Then we can now see the input string and the characters composing in Logcat.
  • #31: Next, here is a high-performance audio library for game development, Oboe. Oboe Achieve the lowest latency, Use the best available native library, Avoid audio bugs. When I developed a mobile game, I used AudioTrack through JNI. But it’s slow and has some bugs depending on the manufacturer, so I made an audio pool myself and used it.
  • #32: Let’s make a beep sound by using Oboe. I got the OboeSinePlayer source code from Google’s oboe repository. Make instance as a member of NativeEngine and play it when getting APP_CMD_INIT_WINDOW. That’s the end of playing through oboe.
  • #33: There is another good library called SwappyGL. It controls the pace of the game’s frames.
  • #34: Figure 2,3 are how short game frames work. It needs EGL_ANDROID_presentation_time extension to be smoother. By using it, Present B is guaranteed to have 2 frames. Figure 4,5 are how long frames work. It needs EGL_KHR_fence_sync extension to make frame C and D wait. By using it, Present B is also guaranteed to have 2 frames.
  • #35: We can check EGL extensions from the Khronos group registry website. eglPresentationTimeANDROID delays frame time. eglClientWaitSyncKHR waits until timeout.
  • #36: Left side is SwappyGL source code in gamesdk repository, Right side is how to setup games-frame-pacing library. Look at the swapInternal function, onPreSwap, onPostSwap functions are calculating swap timing automatically using fence and eglPresentationTimeANDROID.
  • #37: Integrating SwappyGL is so simple. In the constructor, initialize the SwappyGL, and set swap interval. Simple however we need to implement GetJniEnv for passing JNIEnv variable to SwappyGL.
  • #38: In destructor, we will call SwappyGL_destroy. And when APP_CMD_INIT_WINDOW command received, call SwappyGL_setWindow with mApp->window. Finally we replace eglSwapBuffers to SwappyGL_swap. That’s all.
  • #39: The final one, Android performance tuner. Android performance tuner works with android vital in Google play. Each user upload the data with game annotation and fidelity parameters like Firebase Analytics.
  • #40: The android performance tuner’s name is TuningFork. Let’s setup samples into GameActivityTutorial app. We decided to copy protobuf files from agdktunnel sample app. 1. make assets and proto folder. 2. copy proto files, fidelity params text files, and settings text file. 3. add custom task to build.gradle for build proto files.
  • #41: 4. add implementation games-performance-tuner library in build.gradle. 5. and CMakeLists.txt build setup for proto gen files and performance-tuner library. 6. set permissions for application and enable usesCleartextTrafic for http.
  • #42: Next let’s make TuningManager.hpp/cpp. Just copied them for testing from agdktunnel.
  • #43: StartLoading is called by TuningManager constructor, EndLoading is called manually at the first frame rendered.
  • #44: When using SwappyGL we can avoid using Choreographer directly, However, unfortunately, the TuningManager that used in agdktunnel needs to be used Choreographer directly. So minSdk requires 24. We have to set it in build.gradle. We can also have another chance to avoid using Choreographer by SwappyTracer. See the right side. But it is not applied yet in agdktunnel.
  • #45: I checked swappy tracer’s usage from gamesdk sources. We call TuningFork_init with settings and store swappy tracer’s pointer to s_swappy_tracer in tf::Init. As a result, swappy tracer is stored, but nowhere to use it.
  • #46: Finally configure the TuningManager and let's check if it's applied properly. Add TuningManager as a member variable to NativeEngine, create instance in NativeEngine constructor, and delete it in NativeEngine destructor. In DoFrame check first frame, and call FinishLoading of TuningManager. We can see the log to upload but got some issues with uploading. It needs time to find out the reason more.
  • #47: This is end of my presentation. Thank you for your attention. If you have any questions, feel free to ask me.