aboutsummaryrefslogtreecommitdiffstats
path: root/support
diff options
context:
space:
mode:
authorAlan Jeffrey <ajeffrey@mozilla.com>2018-09-12 17:21:51 -0500
committerAlan Jeffrey <ajeffrey@mozilla.com>2018-10-29 08:49:41 -0500
commitdab8f4a97fe8c122d24281ea7c62ccb3c7bba621 (patch)
treefec6a477145188b9dda3713c8ff8992a2f60b030 /support
parente580250d5d99060b0ee8d88e3ff66b6d9ec24050 (diff)
downloadservo-dab8f4a97fe8c122d24281ea7c62ccb3c7bba621.tar.gz
servo-dab8f4a97fe8c122d24281ea7c62ccb3c7bba621.zip
Support building for Magic Leap.
Diffstat (limited to 'support')
-rw-r--r--support/magicleap/.gitignore3
-rw-r--r--support/magicleap/README.md31
-rw-r--r--support/magicleap/Servo2D/.vscode/launch.json65
-rw-r--r--support/magicleap/Servo2D/.vscode/settings.json22
-rw-r--r--support/magicleap/Servo2D/.vscode/tasks.json223
-rw-r--r--support/magicleap/Servo2D/Servo2D.mabu26
-rw-r--r--support/magicleap/Servo2D/Servo2D.mlproject5
-rw-r--r--support/magicleap/Servo2D/Servo2D.package7
-rw-r--r--support/magicleap/Servo2D/code/inc.gen/SceneDescriptor.h48
-rw-r--r--support/magicleap/Servo2D/code/inc.gen/scenesGen.h34
-rw-r--r--support/magicleap/Servo2D/code/inc/Servo2D.h96
-rw-r--r--support/magicleap/Servo2D/code/src.gen/SceneDescriptor.cpp54
-rw-r--r--support/magicleap/Servo2D/code/src.gen/scenesGen.cpp49
-rw-r--r--support/magicleap/Servo2D/code/src/Servo2D.cpp200
-rw-r--r--support/magicleap/Servo2D/code/src/main.cpp13
-rw-r--r--support/magicleap/Servo2D/code/srcsGen.comp3
-rw-r--r--support/magicleap/Servo2D/fonts.xml19
-rw-r--r--support/magicleap/Servo2D/manifest.xml17
-rw-r--r--support/magicleap/Servo2D/pipeline/cache/AssetManifest.comp1
-rw-r--r--support/magicleap/Servo2D/pipeline/lap/project.json36
-rw-r--r--support/magicleap/Servo2D/scenes.comp3
-rw-r--r--support/magicleap/Servo2D/scenes/Servo2D.design177
-rw-r--r--support/magicleap/Servo2D/scenes/Servo2D.scene.res.xml0
-rw-r--r--support/magicleap/Servo2D/scenes/Servo2D.scene.xml15
-rwxr-xr-xsupport/magicleap/fake-ld.sh21
-rwxr-xr-xsupport/magicleap/openssl.sh60
-rw-r--r--support/magicleap/toolchain.cmake1
27 files changed, 1229 insertions, 0 deletions
diff --git a/support/magicleap/.gitignore b/support/magicleap/.gitignore
new file mode 100644
index 00000000000..6ef202d33ef
--- /dev/null
+++ b/support/magicleap/.gitignore
@@ -0,0 +1,3 @@
+.out
+*.log
+*.lock
diff --git a/support/magicleap/README.md b/support/magicleap/README.md
new file mode 100644
index 00000000000..5aee8dbaea8
--- /dev/null
+++ b/support/magicleap/README.md
@@ -0,0 +1,31 @@
+# Servo for Magic Leap
+
+## Build requirements
+
+Currently, we only support building Servo for the Magic Leap on macOS.
+
+Install the Magic Leap Lumin and Lumin Runtime SDKs.
+
+Get a signing key for the magic leap app.
+
+Optionally, install Visual Studio Code and the Magic Leap plugin.
+
+## Building the mlservo library
+
+Build the mlservo library:
+```
+MAGICLEAP_SDK=*directory* ./mach build -d --magicleap
+```
+This builds a static library `target/aarch64-linux-android/debug/libmlservo.a`.
+
+## Building the Servo2D application
+
+From inside the `support/magicleap/Servo2D` directory:
+```
+mabu Servo2D.package -t device -s *signing key*
+```
+This builds the application `.out/Servo2D/Servo2D.mpk`.
+
+Alternatively, in Visual Studio code, open the `support/magicleap/Servo2D` directory,
+and use the `Terminal/Run Build Task...` menu option to build the
+Servo2D application.
diff --git a/support/magicleap/Servo2D/.vscode/launch.json b/support/magicleap/Servo2D/.vscode/launch.json
new file mode 100644
index 00000000000..647968810ff
--- /dev/null
+++ b/support/magicleap/Servo2D/.vscode/launch.json
@@ -0,0 +1,65 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Host OS Debug",
+ "request": "launch",
+ "type": "cppdbg",
+ "stopAtEntry": true,
+ "externalConsole": false,
+ "logging": {
+ "engineLogging": false,
+ "trace": false
+ },
+ "windows": {
+ "type": "cppvsdbg",
+ "cwd": "${workspaceFolder}/.out/${config:lumin_package_name}",
+ "environment": [{"name": "PATH", "value": "${config:lumin_sdk}/VirtualDevice/bin;${config:lumin_sdk}/VirtualDevice/lib;${config:lumin_sdk}/lib/win64;${env.PATH}"}],
+ "program": "${workspaceFolder}/.out/debug_win_${config:lumin_host_toolchain}/${config:lumin_exe_name}.exe"
+ },
+ "osx": {
+ "type": "cppdbg",
+ "MIMode": "lldb",
+ "cwd": "${workspaceFolder}/.out/${config:lumin_package_name}",
+ "environment": [{"name": "DYLD_LIBRARY_PATH", "value": "${config:lumin_sdk}/VirtualDevice/bin:${config:lumin_sdk}/VirtualDevice/lib:${config:lumin_sdk}/lib/osx:${env.DYLD_LIBRARY_PATH}"}],
+ "program": "${workspaceFolder}/.out/debug_osx_${config:lumin_host_toolchain}/${config:lumin_exe_name}"
+ },
+ "linux": {
+ "type": "cppdbg",
+ "MIMode": "lldb",
+ "cwd": "${workspaceFolder}/.out/${config:lumin_package_name}",
+ "environment": [{"name": "LD_LIBRARY_PATH", "value": "${config:lumin_sdk}/VirtualDevice/bin:${config:lumin_sdk}/VirtualDevice/lib:${config:lumin_sdk}/lib/linux64:${env.LD_LIBRARY_PATH}"}],
+ "program": "${workspaceFolder}/.out/debug_linux_${config:lumin_host_toolchain}/${config:lumin_exe_name}"
+ },
+ "preLaunchTask": "Build (Host OS Debug)"
+ },
+ {
+ "name": "Lumin OS Debug",
+ "request": "launch",
+ "type": "cppdbg",
+ "stopAtEntry": true,
+ "externalConsole": false,
+ "logging": {
+ "engineLogging": false,
+ "trace": false
+ },
+ "cwd": "${workspaceFolder}/.out/${config:lumin_package_name}",
+ "targetArchitecture": "arm64",
+ "MIMode": "gdb",
+ "miDebuggerPath": "${config:lumin_sdk}/tools/toolchains/bin/gdb",
+ "windows": {
+ "miDebuggerPath": "${config:lumin_sdk}/tools/toolchains/bin/gdb.exe",
+ },
+ "miDebuggerServerAddress": "localhost:7777",
+ "program": "${workspaceFolder}/.out/debug_lumin_${config:lumin_device_toolchain}/${config:lumin_exe_name}",
+ "customLaunchSetupCommands": [
+ {"text": "-file-exec-and-symbols \"${workspaceFolder}/.out/debug_lumin_${config:lumin_device_toolchain}/${config:lumin_exe_name}\""},
+ {"text": "source ${workspaceFolder}/.out/debug_lumin_${config:lumin_device_toolchain}/${config:lumin_exe_name}.gdbinit"},
+ {"text": "-enable-pretty-printing"},
+ {"text": "continue", "ignoreFailures": true},
+ {"text": "continue", "ignoreFailures": true}
+ ],
+ "preLaunchTask": "Lumin: Setup for remote debugging",
+ }
+ ]
+} \ No newline at end of file
diff --git a/support/magicleap/Servo2D/.vscode/settings.json b/support/magicleap/Servo2D/.vscode/settings.json
new file mode 100644
index 00000000000..b367781dc14
--- /dev/null
+++ b/support/magicleap/Servo2D/.vscode/settings.json
@@ -0,0 +1,22 @@
+{
+ "lumin_mabu_file": "Servo2D.package",
+ "lumin_package_name": "Servo2D",
+ "lumin_exe_name": "Servo2D",
+ "C_Cpp.default.includePath": [
+ "${workspaceFolder}/code/**",
+ "${config.lumin_sdk}/lumin/usr/include/",
+ "${config.lumin_sdk}/include/runtime/app",
+ "${config.lumin_sdk}/include/runtime/core",
+ "${config.lumin_sdk}/include/runtime/external",
+ "${config.lumin_sdk}/include/runtime/intergen",
+ "${config.lumin_sdk}/include/runtime/loader",
+ "${config.lumin_sdk}/include/runtime/uikit",
+ "${config.lumin_sdk}/include/runtime/util",
+ "${config.lumin_sdk}/include/"
+ ],
+ "C_Cpp.default.defines": [
+ "ANDROID"
+ ],
+ "C_Cpp.default.cppStandard": "c++11",
+ "debug.allowBreakpointsEverywhere": true
+}
diff --git a/support/magicleap/Servo2D/.vscode/tasks.json b/support/magicleap/Servo2D/.vscode/tasks.json
new file mode 100644
index 00000000000..c2824f4cf02
--- /dev/null
+++ b/support/magicleap/Servo2D/.vscode/tasks.json
@@ -0,0 +1,223 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build (Lumin OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_debug",
+ "-s",
+ "${config:lumin_cert}"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Clean (Lumin OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_debug",
+ "-c"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Run (Lumin OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_debug",
+ "-s",
+ "${config:lumin_cert}",
+ "--invoke"
+ ],
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Build (Lumin OS Release)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_release",
+ "-s",
+ "${config:lumin_cert}"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Clean (Lumin OS Release)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_release",
+ "-c"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Run (Lumin OS Release)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "device_release",
+ "-s",
+ "${config:lumin_cert}",
+ "--invoke"
+ ],
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Build (Host OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ "options": {
+ "env": {
+ "VisualStudioVersion": "15.0"
+ }
+ }
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "host_debug"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Clean (Host OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "host_debug",
+ "-c"
+ ],
+ "group": "build",
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Run (Host OS Debug)",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/mabu",
+ "windows": {
+ "command": "${config:lumin_sdk}/mabu.cmd",
+ "options": {
+ "env": {
+ "VisualStudioVersion": "15.0",
+ "PATH": "${config:lumin_sdk}/VirtualDevice/bin;${config:lumin_sdk}/VirtualDevice/lib;${config:lumin_sdk}/lib/win64;${env.PATH}"
+ }
+ }
+ },
+ "osx": {
+ "options": {
+ "env": {
+ "ML_LIBRARY_PATH": "${config:lumin_sdk}/VirtualDevice/bin:${config:lumin_sdk}/VirtualDevice/lib:${config:lumin_sdk}/lib/osx"
+ }
+ }
+ },
+ "linux": {
+ "options": {
+ "env": {
+ "LD_LIBRARY_PATH": "${config:lumin_sdk}/VirtualDevice/bin:${config:lumin_sdk}/VirtualDevice/lib:${config:lumin_sdk}/lib/linux64:${env.LD_LIBRARY_PATH}"
+ }
+ }
+ },
+ "args": [
+ "${workspaceFolder}/${config:lumin_mabu_file}",
+ "-t",
+ "host_debug",
+ "--invoke"
+ ],
+ "problemMatcher": [
+ "$msCompile",
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Lumin: Setup for remote debugging",
+ "type": "shell",
+ "command": "${config:lumin_sdk}/debug",
+ "windows": {
+ "command": "${config:lumin_sdk}/debug.cmd",
+ },
+ "args": [
+ "--setup-only",
+ "-v",
+ "--sopaths",
+ "${workspaceFolder}/.out/debug_lumin_${config:lumin_device_toolchain}/",
+ "--deploy-mpk",
+ "${workspaceFolder}/.out/${config:lumin_package_name}/${config:lumin_exe_name}.mpk",
+ "${workspaceFolder}/.out/debug_lumin_${config:lumin_device_toolchain}/${config:lumin_exe_name}"
+ ],
+ "dependsOn": [
+ "Build (Lumin OS Debug)"
+ ]
+ }
+ ]
+}
diff --git a/support/magicleap/Servo2D/Servo2D.mabu b/support/magicleap/Servo2D/Servo2D.mabu
new file mode 100644
index 00000000000..60221b2875b
--- /dev/null
+++ b/support/magicleap/Servo2D/Servo2D.mabu
@@ -0,0 +1,26 @@
+KIND = program
+
+INCS = \
+ code/inc/ \
+ code/inc.gen/
+
+SRCS = \
+ code/src/main.cpp \
+ code/src/Servo2D.cpp
+
+LIBPATHS.debug = \
+ ../../../target/aarch64-linux-android/debug
+
+LIBPATHS.release = \
+ ../../../target/aarch64-linux-android/release
+
+STLIBS = \
+ mlservo
+
+SHLIBS = \
+ log \
+ z
+
+USES = \
+ lumin_runtime \
+ code/srcsGen
diff --git a/support/magicleap/Servo2D/Servo2D.mlproject b/support/magicleap/Servo2D/Servo2D.mlproject
new file mode 100644
index 00000000000..0c6dde70b06
--- /dev/null
+++ b/support/magicleap/Servo2D/Servo2D.mlproject
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="ASCII"?>
+<mlproject:mlproject xmlns:mlproject="http://www.magicleap.com/uidesigner/mlproject" generated="false">
+ <designFile path="scenes/Servo2D.design"/>
+ <pipelineDirectory path="pipeline"/>
+</mlproject:mlproject> \ No newline at end of file
diff --git a/support/magicleap/Servo2D/Servo2D.package b/support/magicleap/Servo2D/Servo2D.package
new file mode 100644
index 00000000000..c8020d772ca
--- /dev/null
+++ b/support/magicleap/Servo2D/Servo2D.package
@@ -0,0 +1,7 @@
+
+USES = "scenes" "pipeline/cache/AssetManifest"
+
+DATAS = \
+ fonts.xml : etc/fonts.xml
+
+REFS = Servo2D \ No newline at end of file
diff --git a/support/magicleap/Servo2D/code/inc.gen/SceneDescriptor.h b/support/magicleap/Servo2D/code/inc.gen/SceneDescriptor.h
new file mode 100644
index 00000000000..db950700a13
--- /dev/null
+++ b/support/magicleap/Servo2D/code/inc.gen/SceneDescriptor.h
@@ -0,0 +1,48 @@
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+//
+// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
+// ANY MODIFICATIONS WILL BE OVERWRITTEN
+//
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+
+// %BANNER_BEGIN%
+// ---------------------------------------------------------------------
+// %COPYRIGHT_BEGIN%
+//
+// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
+// Use of this file is governed by the Creator Agreement, located
+// here: https://id.magicleap.com/creator-terms
+//
+// %COPYRIGHT_END%
+// ---------------------------------------------------------------------
+// %BANNER_END%
+
+#pragma once
+
+#include <string>
+#include <map>
+
+// data class
+class SceneDescriptor {
+ public:
+
+ typedef std::map<std::string /* exportedNodeName */, const std::string& /* exportedNodeId */> ExportedNodeReferences;
+
+ SceneDescriptor(const char* exportedName, const char* id, const char* sceneGraphFilePath, const char* resourceModelFilePath, const ExportedNodeReferences& exportedNodeReferences, bool initiallyInstanced);
+ const std::string& getExportedName() const;
+ const std::string& getId() const;
+ const std::string& getSceneGraphPath() const;
+ const std::string& getResourceModelPath() const;
+ const ExportedNodeReferences & getExportedNodeReferences() const;
+ bool getInitiallyInstanced() const;
+
+ private:
+ std::string exportedName_;
+ std::string id_;
+ std::string sceneGraphPath_;
+ std::string resourceModelPath_;
+ const ExportedNodeReferences& exportedNodeReferences_;
+ bool initiallyInstanced_;
+};
+
+typedef std::map<std::string /* exportedName */, const SceneDescriptor&> SceneDescriptorReferences;
diff --git a/support/magicleap/Servo2D/code/inc.gen/scenesGen.h b/support/magicleap/Servo2D/code/inc.gen/scenesGen.h
new file mode 100644
index 00000000000..eae1ce2e957
--- /dev/null
+++ b/support/magicleap/Servo2D/code/inc.gen/scenesGen.h
@@ -0,0 +1,34 @@
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+//
+// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
+// ANY MODIFICATIONS WILL BE OVERWRITTEN
+//
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+
+// %BANNER_BEGIN%
+// ---------------------------------------------------------------------
+// %COPYRIGHT_BEGIN%
+//
+// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
+// Use of this file is governed by the Creator Agreement, located
+// here: https://id.magicleap.com/creator-terms
+//
+// %COPYRIGHT_END%
+// ---------------------------------------------------------------------
+// %BANNER_END%
+
+#pragma once
+
+#include <SceneDescriptor.h>
+
+namespace Servo2D_exportedNodes {
+ extern const std::string content;
+ extern const std::string backButton;
+ extern const std::string fwdButton;
+ extern const std::string urlBar;
+}
+
+namespace scenes {
+ extern const SceneDescriptor Servo2D;
+ extern const SceneDescriptorReferences exportedScenes;
+}
diff --git a/support/magicleap/Servo2D/code/inc/Servo2D.h b/support/magicleap/Servo2D/code/inc/Servo2D.h
new file mode 100644
index 00000000000..866f2e09e6c
--- /dev/null
+++ b/support/magicleap/Servo2D/code/inc/Servo2D.h
@@ -0,0 +1,96 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <lumin/LandscapeApp.h>
+#include <lumin/Prism.h>
+#include <lumin/event/ServerEvent.h>
+#include <lumin/resource/PlanarResource.h>
+#include <SceneDescriptor.h>
+
+typedef void* ServoInstance;
+
+/**
+ * Servo2D Landscape Application
+ */
+class Servo2D : public lumin::LandscapeApp {
+public:
+ /**
+ * Constructs the Landscape Application.
+ */
+ Servo2D();
+
+ /**
+ * Destroys the Landscape Application.
+ */
+ virtual ~Servo2D();
+
+ /**
+ * Disallows the copy constructor.
+ */
+ Servo2D(const Servo2D&) = delete;
+
+ /**
+ * Disallows the move constructor.
+ */
+ Servo2D(Servo2D&&) = delete;
+
+ /**
+ * Disallows the copy assignment operator.
+ */
+ Servo2D& operator=(const Servo2D&) = delete;
+
+ /**
+ * Disallows the move assignment operator.
+ */
+ Servo2D& operator=(Servo2D&&) = delete;
+
+protected:
+ /**
+ * Initializes the Landscape Application.
+ * @return - 0 on success, error code on failure.
+ */
+ int init() override;
+
+ /**
+ * Deinitializes the Landscape Application.
+ * @return - 0 on success, error code on failure.
+ */
+ int deInit() override;
+
+ /**
+ * Returns the size of the Prism, default = +/- (1.0f, 1.0f, 1.0f) meters.
+ * Used in createPrism().
+ */
+ const glm::vec3 getInitialPrismExtents() const;
+
+ /**
+ * Creates the prism, updates the private variable prism_ with the created prism.
+ */
+ int createInitialPrism();
+
+ /**
+ * Initializes and creates the scene of all scenes marked as initially instanced
+ */
+ void instanceInitialScenes();
+
+ /**
+ * Initializes and creates the scene of the scene and instances it into the prism
+ */
+ lumin::Node* instanceScene(const SceneDescriptor & sceneToInit);
+
+ /**
+ * Run application login
+ */
+ virtual bool updateLoop(float fDelta) override;
+
+ /**
+ * Handle events from the server
+ */
+ virtual bool eventListener(lumin::ServerEvent* event) override;
+
+private:
+ lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
+ lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
+ ServoInstance servo_ = nullptr; // the servo instance we're embedding
+};
diff --git a/support/magicleap/Servo2D/code/src.gen/SceneDescriptor.cpp b/support/magicleap/Servo2D/code/src.gen/SceneDescriptor.cpp
new file mode 100644
index 00000000000..08bb47d61ac
--- /dev/null
+++ b/support/magicleap/Servo2D/code/src.gen/SceneDescriptor.cpp
@@ -0,0 +1,54 @@
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+//
+// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
+// ANY MODIFICATIONS WILL BE OVERWRITTEN
+//
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+
+// %BANNER_BEGIN%
+// ---------------------------------------------------------------------
+// %COPYRIGHT_BEGIN%
+//
+// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
+// Use of this file is governed by the Creator Agreement, located
+// here: https://id.magicleap.com/creator-terms
+//
+// %COPYRIGHT_END%
+// ---------------------------------------------------------------------
+// %BANNER_END%
+
+#include <SceneDescriptor.h>
+
+SceneDescriptor::SceneDescriptor(const char * exportedName, const char * id, const char * sceneGraphPath, const char * resourceModelPath, const ExportedNodeReferences& exportedNodeReferences, bool initiallyInstanced)
+:
+ exportedName_(exportedName),
+ id_(id),
+ sceneGraphPath_(sceneGraphPath),
+ resourceModelPath_(resourceModelPath),
+ exportedNodeReferences_(exportedNodeReferences),
+ initiallyInstanced_(initiallyInstanced) {
+}
+
+const std::string & SceneDescriptor::getExportedName() const {
+ return exportedName_;
+}
+
+const std::string & SceneDescriptor::getId() const {
+ return id_;
+}
+
+const std::string & SceneDescriptor::getSceneGraphPath() const {
+ return sceneGraphPath_;
+}
+
+const std::string & SceneDescriptor::getResourceModelPath() const {
+ return resourceModelPath_;
+}
+
+const SceneDescriptor::ExportedNodeReferences & SceneDescriptor::getExportedNodeReferences() const {
+ return exportedNodeReferences_;
+}
+
+bool SceneDescriptor::getInitiallyInstanced() const {
+ return initiallyInstanced_;
+}
diff --git a/support/magicleap/Servo2D/code/src.gen/scenesGen.cpp b/support/magicleap/Servo2D/code/src.gen/scenesGen.cpp
new file mode 100644
index 00000000000..6c40880be9e
--- /dev/null
+++ b/support/magicleap/Servo2D/code/src.gen/scenesGen.cpp
@@ -0,0 +1,49 @@
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+//
+// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
+// ANY MODIFICATIONS WILL BE OVERWRITTEN
+//
+// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+
+// %BANNER_BEGIN%
+// ---------------------------------------------------------------------
+// %COPYRIGHT_BEGIN%
+//
+// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
+// Use of this file is governed by the Creator Agreement, located
+// here: https://id.magicleap.com/creator-terms
+//
+// %COPYRIGHT_END%
+// ---------------------------------------------------------------------
+// %BANNER_END%
+
+#include <scenesGen.h>
+
+namespace Servo2D_exportedNodes {
+ const std::string content = "content";
+ const std::string backButton = "backButton";
+ const std::string fwdButton = "fwdButton";
+ const std::string urlBar = "urlBar";
+}
+
+namespace scenes {
+
+ const SceneDescriptor::ExportedNodeReferences Servo2D_exportedNodesMap = {
+ {"content", Servo2D_exportedNodes::content},
+ {"backButton", Servo2D_exportedNodes::backButton},
+ {"fwdButton", Servo2D_exportedNodes::fwdButton},
+ {"urlBar", Servo2D_exportedNodes::urlBar}
+ };
+
+ const SceneDescriptor Servo2D(
+ "Servo2D",
+ "root",
+ "/assets/scenes/scenes/Servo2D.scene.xml",
+ "/assets/scenes/scenes/Servo2D.scene.res.xml",
+ Servo2D_exportedNodesMap,
+ true);
+
+ const SceneDescriptorReferences exportedScenes = {
+ {Servo2D.getExportedName(), Servo2D}
+ };
+}
diff --git a/support/magicleap/Servo2D/code/src/Servo2D.cpp b/support/magicleap/Servo2D/code/src/Servo2D.cpp
new file mode 100644
index 00000000000..3d6c0ca905e
--- /dev/null
+++ b/support/magicleap/Servo2D/code/src/Servo2D.cpp
@@ -0,0 +1,200 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <Servo2D.h>
+#include <lumin/node/RootNode.h>
+#include <lumin/node/QuadNode.h>
+#include <lumin/ui/Cursor.h>
+#include <ml_logging.h>
+#include <scenesGen.h>
+#include <SceneDescriptor.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <string.h>
+
+// The viewport dimensions (in px).
+const unsigned int VIEWPORT_W = 500;
+const unsigned int VIEWPORT_H = 500;
+
+// The hidpi factor.
+const float HIDPI = 1.0;
+
+// The prism dimensions (in m).
+const float PRISM_W = 0.5;
+const float PRISM_H = 0.5;
+const float PRISM_D = 0.5;
+
+// A function which calls the ML logger, suitable for passing into Servo
+typedef void (*MLLogger)(MLLogLevel lvl, char* msg);
+void logger(MLLogLevel lvl, char* msg) {
+ if (MLLoggingLogLevelIsEnabled(lvl)) {
+ MLLoggingLog(lvl, ML_DEFAULT_LOG_TAG, msg);
+ }
+}
+
+// The functions Servo provides for hooking up to the ML.
+// For the moment, this doesn't handle input events.
+extern "C" ServoInstance init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
+ const char* url, int width, int height, float hidpi);
+extern "C" void heartbeat_servo(ServoInstance);
+extern "C" void discard_servo(ServoInstance);
+
+// Create a Servo2D instance
+Servo2D::Servo2D() {
+ ML_LOG(Debug, "Servo2D Constructor.");
+}
+
+// Destroy a Servo 2D instance
+Servo2D::~Servo2D() {
+ ML_LOG(Debug, "Servo2D Destructor.");
+ discard_servo(servo_);
+ servo_ = nullptr;
+}
+
+// The prism dimensions
+const glm::vec3 Servo2D::getInitialPrismExtents() const {
+ return glm::vec3(PRISM_W, PRISM_H, PRISM_D);
+}
+
+// Create the prism for Servo
+int Servo2D::createInitialPrism() {
+ prism_ = requestNewPrism(getInitialPrismExtents());
+ if (!prism_) {
+ ML_LOG(Error, "Servo2D Error creating default prism.");
+ return 1;
+ }
+ return 0;
+}
+
+// Initialize a Servo instance
+int Servo2D::init() {
+
+ ML_LOG(Debug, "Servo2D Initializing.");
+
+ // Set up the prism
+ createInitialPrism();
+ lumin::ui::Cursor::SetScale(prism_, 0.03f);
+ instanceInitialScenes();
+
+ // Get the planar resource that holds the EGL context
+ lumin::RootNode* root_node = prism_->getRootNode();
+ if (!root_node) {
+ ML_LOG(Error, "Servo2D Failed to get root node");
+ abort();
+ return 1;
+ }
+
+ std::string content_node_id = Servo2D_exportedNodes::content;
+ lumin::QuadNode* content_node = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
+ if (!content_node) {
+ ML_LOG(Error, "Servo2D Failed to get content node");
+ abort();
+ return 1;
+ }
+
+ lumin::ResourceIDType plane_id = prism_->createPlanarEGLResourceId();
+ if (!plane_id) {
+ ML_LOG(Error, "Servo2D Failed to create EGL resource");
+ abort();
+ return 1;
+ }
+
+ plane_ = static_cast<lumin::PlanarResource*>(prism_->getResource(plane_id));
+ if (!plane_) {
+ ML_LOG(Error, "Servo2D Failed to create plane");
+ abort();
+ return 1;
+ }
+
+ content_node->setRenderResource(plane_id);
+
+ // Get the EGL context, surface and display.
+ EGLContext ctx = plane_->getEGLContext();
+ EGLSurface surf = plane_->getEGLSurface();
+ EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ eglMakeCurrent(dpy, surf, surf, ctx);
+ glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);
+
+ // Hook into servo
+ servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org", VIEWPORT_H, VIEWPORT_W, HIDPI);
+ if (!servo_) {
+ ML_LOG(Error, "Servo2D Failed to init servo instance");
+ abort();
+ return 1;
+ }
+
+ // Flush GL
+ glFlush();
+ eglSwapBuffers(dpy, surf);
+ return 0;
+}
+
+int Servo2D::deInit() {
+ ML_LOG(Debug, "Servo2D Deinitializing.");
+ return 0;
+}
+
+lumin::Node* Servo2D::instanceScene(const SceneDescriptor& scene) {
+ // Load resources.
+ if (!prism_->loadResourceModel(scene.getResourceModelPath())) {
+ ML_LOG(Info, "No resource model loaded");
+ }
+
+ // Load a scene file.
+ std::string editorObjectModelName;
+ if (!prism_->loadObjectModel(scene.getSceneGraphPath(), editorObjectModelName)) {
+ ML_LOG(Error, "Servo2D Failed to load object model");
+ abort();
+ return nullptr;
+ }
+
+ // Add scene to this prism.
+ lumin::Node* newTree = prism_->createAll(editorObjectModelName);
+ if (!prism_->getRootNode()->addChild(newTree)) {
+ ML_LOG(Error, "Servo2D Failed to add newTree to the prism root node");
+ abort();
+ return nullptr;
+ }
+
+ return newTree;
+}
+
+void Servo2D::instanceInitialScenes() {
+ // Iterate over all the exported scenes
+ for (auto& exportedSceneEntry : scenes::exportedScenes ) {
+
+ // If this scene was marked to be instanced at app initialization, do it
+ const SceneDescriptor &sd = exportedSceneEntry.second;
+ if (sd.getInitiallyInstanced()) {
+ instanceScene(sd);
+ }
+ }
+}
+
+bool Servo2D::updateLoop(float fDelta) {
+ // Get the EGL context, surface and display.
+ EGLContext ctx = plane_->getEGLContext();
+ EGLSurface surf = plane_->getEGLSurface();
+ EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ eglMakeCurrent(dpy, surf, surf, ctx);
+ glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);
+
+ // Hook into servo
+ heartbeat_servo(servo_);
+
+ // Flush GL
+ glFlush();
+ eglSwapBuffers(dpy, surf);
+
+ // Return true for your app to continue running, false to terminate the app.
+ return true;
+}
+
+bool Servo2D::eventListener(lumin::ServerEvent* event) {
+
+ // Place your event handling here.
+
+ // Return true if the event is consumed.
+ return false;
+}
diff --git a/support/magicleap/Servo2D/code/src/main.cpp b/support/magicleap/Servo2D/code/src/main.cpp
new file mode 100644
index 00000000000..d8abed18c34
--- /dev/null
+++ b/support/magicleap/Servo2D/code/src/main.cpp
@@ -0,0 +1,13 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <Servo2D.h>
+#include <ml_logging.h>
+
+int main(int argc, char **argv)
+{
+ ML_LOG(Debug, "Servo2D Starting.");
+ Servo2D myApp;
+ return myApp.run();
+}
diff --git a/support/magicleap/Servo2D/code/srcsGen.comp b/support/magicleap/Servo2D/code/srcsGen.comp
new file mode 100644
index 00000000000..d46daea0bbb
--- /dev/null
+++ b/support/magicleap/Servo2D/code/srcsGen.comp
@@ -0,0 +1,3 @@
+SRCS = \
+ src.gen/scenesGen.cpp \
+ src.gen/SceneDescriptor.cpp \
diff --git a/support/magicleap/Servo2D/fonts.xml b/support/magicleap/Servo2D/fonts.xml
new file mode 100644
index 00000000000..c994a7e456b
--- /dev/null
+++ b/support/magicleap/Servo2D/fonts.xml
@@ -0,0 +1,19 @@
+<familyset>
+ <family name="sans-serif">
+ <font weight="300" style="normal">/system/etc/ml/kali/Fonts/Lomino/Light/LominoUI_Lt.ttf</font>
+ <font weight="300" style="italic">/system/etc/ml/kali/Fonts/Lomino/LightItalic/LominoUI_LtIt.ttf</font>
+ <font weight="400" style="normal">/system/etc/ml/kali/Fonts/Lomino/Regular/LominoUI_Rg.ttf</font>
+ <font weight="400" style="italic">/system/etc/ml/kali/Fonts/Lomino/Italic/LominoUI_It.ttf</font>
+ <font weight="500" style="normal">/system/etc/ml/kali/Fonts/Lomino/Medium/LominoUI_Md.ttf</font>
+ <font weight="500" style="italic">/system/etc/ml/kali/Fonts/Lomino/MediumItalic/LominoUI_MdIt.ttf</font>
+ <font weight="700" style="normal">/system/etc/ml/kali/Fonts/Lomino/Bold/LominoUI_Bd.ttf</font>
+ <font weight="700" style="italic">/system/etc/ml/kali/Fonts/Lomino/BoldItalic/LominoUI_BdIt.ttf</font>
+ <font weight="900" style="normal">/system/etc/ml/kali/Fonts/Lomino/ExtraBold/LominoUI_XBd.ttf</font>
+ <font weight="900" style="italic">/system/etc/ml/kali/Fonts/Lomino/ExtraBoldItalic/LominoUI_XBdIt.ttf</font>
+ </family>
+
+ <alias name="arial" to="sans-serif" />
+ <alias name="helvetica" to="sans-serif" />
+ <alias name="tahoma" to="sans-serif" />
+ <alias name="verdana" to="sans-serif" />
+</familyset>
diff --git a/support/magicleap/Servo2D/manifest.xml b/support/magicleap/Servo2D/manifest.xml
new file mode 100644
index 00000000000..81fc300b097
--- /dev/null
+++ b/support/magicleap/Servo2D/manifest.xml
@@ -0,0 +1,17 @@
+<manifest
+ xmlns:ml="magicleap"
+ ml:package="com.mozilla.servo2d"
+ ml:version_code="1"
+ ml:version_name="1.0">
+ <application
+ ml:visible_name="Servo2D"
+ ml:sdk_version="1.0">
+ <component
+ ml:name=".servo2d.universe"
+ ml:visible_name="Servo2D"
+ ml:binary_name="bin/Servo2D"
+ ml:type="Universe">
+ </component>
+ <uses-privilege ml:name="Internet"/>
+ </application>
+</manifest>
diff --git a/support/magicleap/Servo2D/pipeline/cache/AssetManifest.comp b/support/magicleap/Servo2D/pipeline/cache/AssetManifest.comp
new file mode 100644
index 00000000000..a1c45b39d6b
--- /dev/null
+++ b/support/magicleap/Servo2D/pipeline/cache/AssetManifest.comp
@@ -0,0 +1 @@
+DATAS= \ No newline at end of file
diff --git a/support/magicleap/Servo2D/pipeline/lap/project.json b/support/magicleap/Servo2D/pipeline/lap/project.json
new file mode 100644
index 00000000000..db27f7df84a
--- /dev/null
+++ b/support/magicleap/Servo2D/pipeline/lap/project.json
@@ -0,0 +1,36 @@
+{
+ "intermediate-storage": {
+ "path": "cache",
+ "kind": "in-tree"
+ },
+ "project-schema-version": 4,
+ "types": {
+ "assets": [
+ "lap/types/asset/material",
+ "lap/types/asset/model",
+ "lap/types/asset/outline-font",
+ "lap/types/asset/texture"
+ ],
+ "files": [
+ "lap/types/file/dds",
+ "lap/types/file/fbx",
+ "lap/types/file/files",
+ "lap/types/file/gltf",
+ "lap/types/file/jpg",
+ "lap/types/file/kmat",
+ "lap/types/file/otf",
+ "lap/types/file/png"
+ ]
+ },
+ "checkpoint-hash": "74689acde6571e19f86366dd94d8890be66acfceb26d14ac3ca14228fa31959087b8771fbb5a86764b4e7dc121bd78c3b0ee4c9c0716f0d91c90a59315f8acd8",
+ "templates": [
+ "lap/template/passthru_material_from_kmat",
+ "lap/template/passthru_model_from_fbx",
+ "lap/template/passthru_model_from_gltf",
+ "lap/template/passthru_outline_font_from_otf",
+ "lap/template/passthru_texture_from_dds",
+ "lap/template/passthru_texture_from_jpg",
+ "lap/template/passthru_texture_from_png"
+ ],
+ "nodes": {}
+} \ No newline at end of file
diff --git a/support/magicleap/Servo2D/scenes.comp b/support/magicleap/Servo2D/scenes.comp
new file mode 100644
index 00000000000..a5c3213a275
--- /dev/null
+++ b/support/magicleap/Servo2D/scenes.comp
@@ -0,0 +1,3 @@
+DATAS = \
+ scenes/Servo2D.scene.res.xml : assets/scenes/scenes/Servo2D.scene.res.xml \
+ scenes/Servo2D.scene.xml : assets/scenes/scenes/Servo2D.scene.xml
diff --git a/support/magicleap/Servo2D/scenes/Servo2D.design b/support/magicleap/Servo2D/scenes/Servo2D.design
new file mode 100644
index 00000000000..0def50dc082
--- /dev/null
+++ b/support/magicleap/Servo2D/scenes/Servo2D.design
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="ASCII"?>
+<design:rootNode xmlns:design="http://www.magicleap.com/uidesigner/rcp/document/design" name="root" nodeTypeId="lumin.root" modelId="lumin" version="1.7.2">
+ <property id="name" value="root"/>
+ <node name="content" nodeTypeId="lumin.quad">
+ <property id="color">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="externalName" value="content"/>
+ <property id="name" value="content"/>
+ <property id="position">
+ <property id="x" value="-0.25"/>
+ <property id="y" value="-0.19"/>
+ </property>
+ <property id="rotation"/>
+ <property id="scale">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ <property id="z" value="1.0"/>
+ </property>
+ <property id="size">
+ <property id="x" value="0.5"/>
+ <property id="y" value="0.44"/>
+ </property>
+ <property id="texCoords">
+ <property id="x">
+ <property id="y" value="1.0"/>
+ </property>
+ <property id="y">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ </property>
+ <property id="z">
+ <property id="x" value="1.0"/>
+ </property>
+ <property id="w"/>
+ </property>
+ </node>
+ <node name="uiLinearLayout1" nodeTypeId="lumin.ui.linearLayout">
+ <property id="alignment">
+ <property id="horizontalAlignment" value="Center"/>
+ </property>
+ <property id="defaultItemAlignment">
+ <property id="verticalAlignment" value="Center"/>
+ </property>
+ <property id="defaultItemPadding">
+ <property id="right" value="0.01"/>
+ <property id="left" value="0.01"/>
+ </property>
+ <property id="gravityWellProperties">
+ <property id="boundaryShape">
+ <property id="size"/>
+ <property id="offset"/>
+ </property>
+ </property>
+ <property id="itemAlignment"/>
+ <property id="itemPadding"/>
+ <property id="name" value="uiLinearLayout1"/>
+ <property id="orientation" value="Horizontal"/>
+ <property id="position">
+ <property id="y" value="-0.2"/>
+ </property>
+ <property id="rotation"/>
+ <property id="scale">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ <property id="z" value="1.0"/>
+ </property>
+ <property id="size">
+ <property id="x" value="0.5"/>
+ <property id="y" value="0.05"/>
+ </property>
+ <node name="backButton" nodeTypeId="lumin.ui.button">
+ <property id="externalName" value="backButton"/>
+ <property id="gravityWellProperties">
+ <property id="boundaryShape">
+ <property id="size"/>
+ <property id="offset"/>
+ </property>
+ </property>
+ <property id="height" value="0.1"/>
+ <property id="iconColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="iconSize"/>
+ <property id="name" value="backButton"/>
+ <property id="position">
+ <property id="y" value="-0.6"/>
+ </property>
+ <property id="rotation"/>
+ <property id="scale">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ <property id="z" value="1.0"/>
+ </property>
+ <property id="text" value="Back"/>
+ <property id="textColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="textSize" value="0.05"/>
+ <property id="textSizeChanged" value="true"/>
+ <property id="width" value="0.1"/>
+ </node>
+ <node name="fwdButton" nodeTypeId="lumin.ui.button">
+ <property id="externalName" value="fwdButton"/>
+ <property id="gravityWellProperties">
+ <property id="boundaryShape">
+ <property id="size"/>
+ <property id="offset"/>
+ </property>
+ </property>
+ <property id="height" value="0.1"/>
+ <property id="iconColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="iconSize"/>
+ <property id="name" value="fwdButton"/>
+ <property id="position"/>
+ <property id="rotation"/>
+ <property id="scale">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ <property id="z" value="1.0"/>
+ </property>
+ <property id="text" value="Fwd"/>
+ <property id="textColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="textSize" value="0.05"/>
+ <property id="textSizeChanged" value="true"/>
+ <property id="width" value="0.1"/>
+ </node>
+ <node name="urlBar" nodeTypeId="lumin.ui.textEdit">
+ <property id="alignment">
+ <property id="verticalAlignment" value="Center"/>
+ </property>
+ <property id="externalName" value="urlBar"/>
+ <property id="gravityWellProperties">
+ <property id="boundaryShape">
+ <property id="size"/>
+ <property id="offset"/>
+ </property>
+ </property>
+ <property id="height" value="0.05"/>
+ <property id="hintTextColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="name" value="urlBar"/>
+ <property id="position"/>
+ <property id="rotation"/>
+ <property id="scale">
+ <property id="x" value="1.0"/>
+ <property id="y" value="1.0"/>
+ <property id="z" value="1.0"/>
+ </property>
+ <property id="scrollBarVisibilityMode" value="Off"/>
+ <property id="text" value="https://servo.org/"/>
+ <property id="textColor">
+ <property id="rgb" value="1 1 1"/>
+ <property id="alpha" value="1.0"/>
+ </property>
+ <property id="textPadding">
+ <property id="top" value="0.003"/>
+ <property id="right" value="0.003"/>
+ <property id="bottom" value="0.003"/>
+ <property id="left" value="0.003"/>
+ </property>
+ <property id="textSize" value="0.05"/>
+ <property id="width" value="0.6"/>
+ </node>
+ </node>
+</design:rootNode> \ No newline at end of file
diff --git a/support/magicleap/Servo2D/scenes/Servo2D.scene.res.xml b/support/magicleap/Servo2D/scenes/Servo2D.scene.res.xml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/support/magicleap/Servo2D/scenes/Servo2D.scene.res.xml
diff --git a/support/magicleap/Servo2D/scenes/Servo2D.scene.xml b/support/magicleap/Servo2D/scenes/Servo2D.scene.xml
new file mode 100644
index 00000000000..ad895bc4d5c
--- /dev/null
+++ b/support/magicleap/Servo2D/scenes/Servo2D.scene.xml
@@ -0,0 +1,15 @@
+<ObjectModel name="Servo2D" version="1">
+ <TransformNode/>
+ <QuadNode castShadow="false" name="content" pos="-0.250000, -0.190000, 0.000000" receiveShadow="false" shader="UnlitColorTex2d" size="0.500000, 0.440000"/>
+ <UiLinearLayout alignment="Top, Center" gravityWellEnabled="false" gravityWellRoundness="0.000000" gravityWellSize="0.000000, 0.000000" gravityWellSnap="ClosestEdge" itemAlignment="Center, Left" itemPadding="0.000000, 0.010000, 0.000000, 0.010000" name="uiLinearLayout1" orientation="Horizontal" pos="0.000000, -0.200000, 0.000000" size="0.500000, 0.050000">
+ <Content>
+ <UiButton gravityWellEnabled="false" gravityWellRoundness="0.000000" gravityWellSize="0.000000, 0.000000" gravityWellSnap="ClosestEdge" name="backButton" pos="0.000000, -0.600000, 0.000000" size="0.100000, 0.100000" text="Back" textSize="0.050000"/>
+ </Content>
+ <Content>
+ <UiButton gravityWellEnabled="false" gravityWellRoundness="0.000000" gravityWellSize="0.000000, 0.000000" gravityWellSnap="ClosestEdge" name="fwdButton" size="0.100000, 0.100000" text="Fwd" textSize="0.050000"/>
+ </Content>
+ <Content>
+ <UiTextEdit alignment="Center, Left" font="" gravityWellEnabled="false" gravityWellRoundness="0.000000" gravityWellSize="0.000000, 0.000000" gravityWellSnap="ClosestEdge" name="urlBar" scrollSpeed="0.500000" size="0.600000, 0.050000" text="https://servo.org/" textSize="0.050000"/>
+ </Content>
+ </UiLinearLayout>
+</ObjectModel>
diff --git a/support/magicleap/fake-ld.sh b/support/magicleap/fake-ld.sh
new file mode 100755
index 00000000000..99c01c3a5ce
--- /dev/null
+++ b/support/magicleap/fake-ld.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+MAGICLEAP_TOOLCHAIN=${MAGICLEAP_TOOLCHAIN:-"${MAGICLEAP_SDK}/tools/toolchains"}
+TARGET=${TARGET:-"aarch64-linux-android"}
+LD=${LD:-"${MAGICLEAP_TOOLCHAIN}/bin/${TARGET}-ld"}
+LDFLAGS=${LDFLAGS:-"-L${MAGICLEAP_SDK}/lumin/stl/libc++/lib -L${MAGICLEAP_SDK}/lumin/usr/lib -L${MAGICLEAP_TOOLCHAIN}/lib/gcc/${TARGET}/4.9.x ${MAGICLEAP_SDK}/lumin/usr/lib/crtbegin_so.o"}
+
+# Remove the -landroid flag, grr
+ARGS=("$@")
+ARGS=${ARGS[@]/-landroid}
+
+echo ${LD} ${LDFLAGS} ${ARGS}
+${LD} ${LDFLAGS} ${ARGS}
diff --git a/support/magicleap/openssl.sh b/support/magicleap/openssl.sh
new file mode 100755
index 00000000000..d45b84ec83a
--- /dev/null
+++ b/support/magicleap/openssl.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+if [[ -z "${OPENSSL_DIR}" ]]; then
+ echo "No OPENSSL_DIR."
+ exit 1
+fi
+
+if [[ -z "${OPENSSL_VERSION}" ]]; then
+ echo "No OPENSSL_VERSION."
+ exit 1
+fi
+
+if [[ -f "${OPENSSL_DIR}/lib/libssl.so" ]] && \
+ [[ "${OPENSSL_DIR}/lib/libssl.so" -nt "${0}" ]] ; then
+ exit 0
+fi
+
+echo "Building ${OPENSSL_DIR}/lib/libssl.so"
+
+S3_BUCKET="https://s3.amazonaws.com/servo-deps/android-deps"
+S3_URL="${S3_BUCKET}/openssl-${OPENSSL_VERSION}.tar.gz"
+
+if [[ ! -d "${OPENSSL_DIR}/src/openssl-${OPENSSL_VERSION}" ]]; then
+ mkdir -p "${OPENSSL_DIR}/src"
+ curl "${S3_URL}" | tar xzf - -C "${OPENSSL_DIR}/src"
+fi
+
+if [[ ! -d "${OPENSSL_DIR}/src/openssl-${OPENSSL_VERSION}" ]]; then
+ echo "Failed to download ${OPENSSL_DIR}/src/openssl-${OPENSSL_VERSION}"
+ exit 1
+fi
+
+cd "${OPENSSL_DIR}/src/openssl-${OPENSSL_VERSION}"
+
+./Configure shared \
+ --prefix="${OPENSSL_DIR}" \
+ --openssldir="${OPENSSL_DIR}" \
+ -no-ssl2 -no-ssl3 -no-comp -no-engine -no-hw \
+ linux-generic64 \
+ -fPIC -fno-omit-frame-pointer \
+ -Wall -Wno-error=macro-redefined -Wno-unknown-attributes \
+ ${CFLAGS:-}
+
+make depend
+make all
+make install_sw
+
+if [[ ! -f "${OPENSSL_DIR}/lib/libssl.so" ]]; then
+ echo "Failed to build ${OPENSSL_DIR}/lib/libssl.so"
+ exit 1
+fi
+
diff --git a/support/magicleap/toolchain.cmake b/support/magicleap/toolchain.cmake
new file mode 100644
index 00000000000..99c23014a7a
--- /dev/null
+++ b/support/magicleap/toolchain.cmake
@@ -0,0 +1 @@
+set(CMAKE_SYSTEM_NAME Linux)