• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <android/native_window_jni.h>
18 #include <android_native_app_glue.h>
19 
20 #include <chrono>
21 #include <thread>
22 
23 #include "vulkan_renderer.h"
24 
25 struct AppState {
26     VulkanRenderer renderer;
27     bool canRender = false;
28 };
29 
onAppCmd(struct android_app * app,int32_t cmd)30 static void onAppCmd(struct android_app *app, int32_t cmd) {
31     auto *appState = (AppState *)app->userData;
32     switch (cmd) {
33         case APP_CMD_START:
34             if (app->window != nullptr) {
35                 appState->renderer.reset(app->window, app->activity->assetManager);
36                 appState->renderer.init();
37                 appState->canRender = true;
38             }
39         case APP_CMD_INIT_WINDOW:
40             if (app->window != nullptr) {
41                 appState->renderer.reset(app->window, app->activity->assetManager);
42                 if (!appState->renderer.initialized) {
43                     appState->renderer.init();
44                 }
45                 appState->canRender = true;
46             }
47             break;
48         case APP_CMD_TERM_WINDOW:
49             appState->canRender = false;
50             break;
51         case APP_CMD_DESTROY:
52             appState->renderer.cleanup();
53         default:
54             break;
55     }
56 }
57 
android_main(struct android_app * app)58 void android_main(struct android_app *app) {
59     AppState appState{};
60 
61     app->userData = &appState;
62     app->onAppCmd = onAppCmd;
63 
64     int frame = 0;
65 
66     while (true) {
67         int ident;
68         int events;
69         android_poll_source *source;
70         while ((ident = ALooper_pollOnce(appState.canRender ? 0 : -1, nullptr, &events,
71                                          (void **)&source)) >= 0) {
72             if (source != nullptr) {
73                 source->process(app, source);
74             }
75         }
76 
77         appState.renderer.render();
78         if (++frame % 10 == 0) {
79             std::this_thread::sleep_for(std::chrono::milliseconds(200));
80         }
81     }
82 }