aboutsummaryrefslogtreecommitdiff
path: root/demos/smoke/ShellAndroid.cpp
diff options
context:
space:
mode:
authorTony Barbour <tony@LunarG.com>2016-02-25 15:44:10 -0700
committerTony Barbour <tony@LunarG.com>2016-02-26 13:53:07 -0700
commit6d366c23f50752c8bc39673416040d89a94a586f (patch)
tree7a9493a747ffad8b708fd373ffbee359459ddd66 /demos/smoke/ShellAndroid.cpp
parent2e4f6dfe4624d966fb4db3c477586bd6b1c2b8e1 (diff)
downloadusermoji-6d366c23f50752c8bc39673416040d89a94a586f.tar.xz
demos: Add Hologram snapshot as Smoke test/demo
Diffstat (limited to 'demos/smoke/ShellAndroid.cpp')
-rw-r--r--demos/smoke/ShellAndroid.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/demos/smoke/ShellAndroid.cpp b/demos/smoke/ShellAndroid.cpp
new file mode 100644
index 00000000..4b813b46
--- /dev/null
+++ b/demos/smoke/ShellAndroid.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <cassert>
+#include <dlfcn.h>
+#include <time.h>
+#include <android/log.h>
+
+#include "Helpers.h"
+#include "Game.h"
+#include "ShellAndroid.h"
+
+namespace {
+
+// copied from ShellXCB.cpp
+class PosixTimer {
+public:
+ PosixTimer()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ clock_gettime(CLOCK_MONOTONIC, &start_);
+ }
+
+ double get() const
+ {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ constexpr long one_s_in_ns = 1000 * 1000 * 1000;
+ constexpr double one_s_in_ns_d = static_cast<double>(one_s_in_ns);
+
+ time_t s = now.tv_sec - start_.tv_sec;
+ long ns;
+ if (now.tv_nsec > start_.tv_nsec) {
+ ns = now.tv_nsec - start_.tv_nsec;
+ } else {
+ assert(s > 0);
+ s--;
+ ns = one_s_in_ns - (start_.tv_nsec - now.tv_nsec);
+ }
+
+ return static_cast<double>(s) + static_cast<double>(ns) / one_s_in_ns_d;
+ }
+
+private:
+ struct timespec start_;
+};
+
+} // namespace
+
+ShellAndroid::ShellAndroid(android_app &app, Game &game) : Shell(game), app_(app)
+{
+ instance_extensions_.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
+
+ app_dummy();
+ app_.userData = this;
+ app_.onAppCmd = on_app_cmd;
+ app_.onInputEvent = on_input_event;
+
+ init_vk();
+}
+
+ShellAndroid::~ShellAndroid()
+{
+ cleanup_vk();
+ dlclose(lib_handle_);
+}
+
+void ShellAndroid::log(LogPriority priority, const char *msg)
+{
+ int prio;
+
+ switch (priority) {
+ case LOG_DEBUG:
+ prio = ANDROID_LOG_DEBUG;
+ break;
+ case LOG_INFO:
+ prio = ANDROID_LOG_INFO;
+ break;
+ case LOG_WARN:
+ prio = ANDROID_LOG_WARN;
+ break;
+ case LOG_ERR:
+ prio = ANDROID_LOG_ERROR;
+ break;
+ default:
+ prio = ANDROID_LOG_UNKNOWN;
+ break;
+ }
+
+ __android_log_write(prio, settings_.name.c_str(), msg);
+}
+
+PFN_vkGetInstanceProcAddr ShellAndroid::load_vk()
+{
+ const char filename[] = "libvulkan.so";
+ void *handle = nullptr, *symbol = nullptr;
+
+ handle = dlopen(filename, RTLD_LAZY);
+ if (handle)
+ symbol = dlsym(handle, "vkGetInstanceProcAddr");
+ if (!symbol) {
+ if (handle)
+ dlclose(handle);
+
+ throw std::runtime_error(dlerror());
+ }
+
+ lib_handle_ = handle;
+
+ return reinterpret_cast<PFN_vkGetInstanceProcAddr>(symbol);
+}
+
+VkSurfaceKHR ShellAndroid::create_surface(VkInstance instance)
+{
+ VkAndroidSurfaceCreateInfoKHR surface_info = {};
+ surface_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ surface_info.window = app_.window;
+
+ VkSurfaceKHR surface;
+ vk::assert_success(vk::CreateAndroidSurfaceKHR(instance, &surface_info, nullptr, &surface));
+
+ return surface;
+}
+
+void ShellAndroid::on_app_cmd(int32_t cmd)
+{
+ switch (cmd) {
+ case APP_CMD_INIT_WINDOW:
+ create_context();
+ resize_swapchain(0, 0);
+ break;
+ case APP_CMD_TERM_WINDOW:
+ destroy_context();
+ break;
+ case APP_CMD_WINDOW_RESIZED:
+ resize_swapchain(0, 0);
+ break;
+ case APP_CMD_STOP:
+ ANativeActivity_finish(app_.activity);
+ break;
+ default:
+ break;
+ }
+}
+
+int32_t ShellAndroid::on_input_event(const AInputEvent *event)
+{
+ if (AInputEvent_getType(event) != AINPUT_EVENT_TYPE_MOTION)
+ return false;
+
+ bool handled = false;
+
+ switch (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) {
+ case AMOTION_EVENT_ACTION_UP:
+ game_.on_key(Game::KEY_SPACE);
+ handled = true;
+ break;
+ default:
+ break;
+ }
+
+ return handled;
+}
+
+void ShellAndroid::quit()
+{
+ ANativeActivity_finish(app_.activity);
+}
+
+void ShellAndroid::run()
+{
+ PosixTimer timer;
+
+ double current_time = timer.get();
+
+ while (true) {
+ struct android_poll_source *source;
+ while (true) {
+ int timeout = (settings_.animate && app_.window) ? 0 : -1;
+ if (ALooper_pollAll(timeout, nullptr, nullptr,
+ reinterpret_cast<void **>(&source)) < 0)
+ break;
+
+ if (source)
+ source->process(&app_, source);
+ }
+
+ if (app_.destroyRequested)
+ break;
+
+ if (!app_.window)
+ continue;
+
+ acquire_back_buffer();
+
+ double t = timer.get();
+ add_game_time(static_cast<float>(t - current_time));
+
+ present_back_buffer();
+
+ current_time = t;
+ }
+}