1 // Copyright (C) 2024 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <cstdlib>
16 #include <memory>
17 
18 #include <android_native_app_glue.h>
19 #include <assert.h>
20 
21 #include "common.h"
22 #include "sample_base.h"
23 
24 namespace cuttlefish {
25 
26 struct AppState {
27   bool drawing = false;
28   std::unique_ptr<SampleBase> sample;
29 };
30 
OnAppCmd(struct android_app * app,int32_t cmd)31 static void OnAppCmd(struct android_app* app, int32_t cmd) {
32   auto* state = reinterpret_cast<AppState*>(app->userData);
33 
34   switch (cmd) {
35     case APP_CMD_START: {
36       ALOGD("APP_CMD_START");
37       if (app->window != nullptr) {
38         state->drawing = true;
39         VK_ASSERT(state->sample->SetWindow(app->window));
40       }
41       break;
42     }
43     case APP_CMD_INIT_WINDOW: {
44       ALOGD("APP_CMD_INIT_WINDOW");
45       if (app->window != nullptr) {
46         state->drawing = true;
47         VK_ASSERT(state->sample->SetWindow(app->window));
48       }
49       break;
50     }
51     case APP_CMD_TERM_WINDOW: {
52       ALOGD("APP_CMD_TERM_WINDOW");
53       state->drawing = false;
54       VK_ASSERT(state->sample->SetWindow(nullptr));
55       break;
56     }
57     case APP_CMD_DESTROY: {
58       ALOGD("APP_CMD_DESTROY");
59       state->drawing = false;
60       break;
61     }
62     default:
63       break;
64   }
65 }
66 
Main(struct android_app * app)67 void Main(struct android_app* app) {
68   AppState state;
69   state.sample = VK_ASSERT(BuildVulkanSampleApp());
70 
71   app->userData = &state;
72 
73   // Invoked from the source->process() below:
74   app->onAppCmd = OnAppCmd;
75 
76   while (true) {
77     int ident;
78     android_poll_source* source;
79     while ((ident = ALooper_pollOnce(state.drawing ? 0 : -1, nullptr, nullptr,
80                                      (void**)&source)) > ALOOPER_POLL_TIMEOUT) {
81       if (source != nullptr) {
82         source->process(app, source);
83       }
84       if (app->destroyRequested != 0) {
85         break;
86       }
87     }
88 
89     if (app->destroyRequested != 0) {
90       ANativeActivity_finish(app->activity);
91       break;
92     }
93 
94     if (state.drawing) {
95       VK_ASSERT(state.sample->Render());
96     }
97   }
98 
99   state.sample->CleanUp();
100   state.sample.reset();
101 }
102 
103 }  // namespace cuttlefish
104 
android_main(struct android_app * app)105 void android_main(struct android_app* app) { cuttlefish::Main(app); }
106