• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Amber Authors.
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 <android/log.h>
16 #include <android/looper.h>
17 #include <android_native_app_glue.h>
18 
19 #include "amber/amber.h"
20 #include "amber/recipe.h"
21 #include "amber/result.h"
22 #include "amber_script.h"
23 
24 namespace {
25 
26 // TODO(jaebaek): Change this as a method rather than macro.
27 // Android log function wrappers
28 const char* kTAG = "Amber";
29 #define LOGE(...) \
30   ((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__))
31 
amber_sample_main(android_app * app)32 void amber_sample_main(android_app* app) {
33   amber::android::AmberScriptLoader loader(app);
34 
35   amber::Result r = loader.LoadAllScriptsFromAsset();
36   if (!r.IsSuccess()) {
37     LOGE("%s", r.Error().c_str());
38     return;
39   }
40 
41   const auto& script_info = loader.GetScripts();
42 
43   std::vector<std::string> failures;
44   for (const auto& info : script_info) {
45     LOGE("\ncase %s: run...", info.asset_name.c_str());
46 
47     amber::Amber am;
48     amber::Recipe recipe;
49     amber::Result r = am.Parse(info.script_content, &recipe);
50     if (!r.IsSuccess()) {
51       LOGE("\ncase %s: fail\n\t%s", info.asset_name.c_str(), r.Error().c_str());
52       failures.push_back(info.asset_name);
53       continue;
54     }
55 
56     amber::Options amber_options;
57     r = am.ExecuteWithShaderData(&recipe, amber_options, info.shader_map);
58     if (!r.IsSuccess()) {
59       LOGE("\ncase %s: fail\n\t%s", info.asset_name.c_str(), r.Error().c_str());
60       failures.push_back(info.asset_name);
61       continue;
62     }
63 
64     LOGE("\ncase %s: pass", info.asset_name.c_str());
65   }
66 
67   if (!failures.empty()) {
68     LOGE("\nSummary of Failures:");
69     for (const auto& failure : failures)
70       LOGE("%s", failure.c_str());
71   }
72   LOGE("\nsummary: %u pass, %u fail",
73        static_cast<uint32_t>(script_info.size() - failures.size()),
74        static_cast<uint32_t>(failures.size()));
75 }
76 
77 // Process the next main command.
handle_cmd(android_app * app,int32_t cmd)78 void handle_cmd(android_app* app, int32_t cmd) {
79   switch (cmd) {
80     case APP_CMD_INIT_WINDOW:
81       amber_sample_main(app);
82       break;
83     case APP_CMD_TERM_WINDOW:
84       break;
85     default:
86       break;
87   }
88 }
89 
90 }  // namespace
91 
android_main(struct android_app * app)92 void android_main(struct android_app* app) {
93   // Set the callback to process system events
94   app->onAppCmd = handle_cmd;
95 
96   // Used to poll the events in the main loop
97   android_poll_source* source;
98 
99   // Main loop
100   while (app->destroyRequested == 0) {
101     auto result = ALooper_pollOnce(1, nullptr, nullptr, (void**)&source);
102     if (result == ALOOPER_POLL_ERROR) {
103       LOGE("ALooper_pollOnce returned an error.");
104       exit(1);
105     }
106 
107     if (result >= 0 && source != nullptr) {
108         source->process(app, source);
109     }
110   }
111 }
112