Skip to content

[3.x] [tvOS] Basic tvOS Support #45829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/tvos_builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: 📺 tvOS Builds
on: [push, pull_request]

# Global Settings
env:
GODOT_BASE_BRANCH: 3.2
SCONSFLAGS: platform=tvos verbose=yes warnings=all werror=yes --jobs=2
SCONS_CACHE_LIMIT: 4096

jobs:
tvos-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)

steps:
- uses: actions/checkout@v2

# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: tvos-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}

# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'

# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version

- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no
ls -l bin/

- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
65 changes: 65 additions & 0 deletions doc/classes/EditorExportPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,71 @@
Adds a static lib from the given [code]path[/code] to the iOS project.
</description>
</method>
<method name="add_tvos_bundle_file">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
Adds an tvOS bundle file from the given [code]path[/code] to the exported project.
</description>
</method>
<method name="add_tvos_cpp_code">
<return type="void">
</return>
<argument index="0" name="code" type="String">
</argument>
<description>
Adds a C++ code to the tvOS export. The final code is created from the code appended by each active export plugin.
</description>
</method>
<method name="add_tvos_embedded_framework">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
Adds a dynamic library (*.dylib, *.framework) to Linking Phase in tvOS's Xcode project and embeds it into resulting binary.
[b]Note:[/b] For static libraries (*.a) works in same way as [method add_ios_framework].
This method should not be used for System libraries as they are already present on the device.
</description>
</method>
<method name="add_tvos_framework">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in tvOS's Xcode project.
</description>
</method>
<method name="add_tvos_linker_flags">
<return type="void">
</return>
<argument index="0" name="flags" type="String">
</argument>
<description>
Adds linker flags for the tvOS export.
</description>
</method>
<method name="add_tvos_plist_content">
<return type="void">
</return>
<argument index="0" name="plist_content" type="String">
</argument>
<description>
Adds content for tvOS Property List files.
</description>
</method>
<method name="add_tvos_project_static_lib">
<return type="void">
</return>
<argument index="0" name="path" type="String">
</argument>
<description>
Adds a static lib from the given [code]path[/code] to the tvOS project.
</description>
</method>
<method name="add_shared_object">
<return type="void">
</return>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@
<member name="input_devices/pointing/ios/touch_delay" type="float" setter="" getter="" default="0.15">
Default delay for touch events. This only affects iOS devices.
</member>
<member name="input_devices/pointing/tvos/press_end_delay" type="float" setter="" getter="" default="0.15">
Default delay for end press events. This only affects tvOS devices.
</member>
<member name="layer_names/2d_physics/layer_1" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 1.
</member>
Expand Down
4 changes: 2 additions & 2 deletions drivers/gles2/rasterizer_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
#endif
#endif

#ifndef IPHONE_ENABLED
#if !defined(IPHONE_ENABLED) && !defined(TVOS_ENABLED)
// We include EGL below to get debug callback on GLES2 platforms,
// but EGL is not available on iOS.
// but EGL is not available on tvOS/iOS.
#define CAN_DEBUG
#endif

Expand Down
6 changes: 3 additions & 3 deletions drivers/gles2/rasterizer_scene_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#endif

#ifndef GLES_OVER_GL
#ifdef IPHONE_ENABLED
#if defined(IPHONE_ENABLED) || defined(TVOS_ENABLED)
#include <OpenGLES/ES2/glext.h>
//void *glResolveMultisampleFramebufferAPPLE;

Expand Down Expand Up @@ -2778,7 +2778,7 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#elif IPHONE_ENABLED
#elif IPHONE_ENABLED || TVOS_ENABLED

glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, next_buffer);
Expand Down Expand Up @@ -3518,7 +3518,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#elif IPHONE_ENABLED
#elif IPHONE_ENABLED || TVOS_ENABLED

glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
Expand Down
6 changes: 3 additions & 3 deletions drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#include <dlfcn.h> // needed to load extensions
#endif

#ifdef IPHONE_ENABLED
#if defined(IPHONE_ENABLED) || defined(TVOS_ENABLED)

#include <OpenGLES/ES2/glext.h>
//void *glRenderbufferStorageMultisampleAPPLE;
Expand Down Expand Up @@ -4931,7 +4931,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth);

#if defined(GLES_OVER_GL) || defined(IPHONE_ENABLED)
#if defined(GLES_OVER_GL) || defined(IPHONE_ENABLED) || defined(TVOS_ENABLED)

glGenRenderbuffers(1, &rt->multisample_color);
glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color);
Expand Down Expand Up @@ -6115,7 +6115,7 @@ void RasterizerStorageGLES2::initialize() {
#ifndef GLES_OVER_GL
//Manually load extensions for android and ios

#ifdef IPHONE_ENABLED
#if defined(IPHONE_ENABLED) || defined(TVOS_ENABLED)
// appears that IPhone doesn't need to dlopen TODO: test this rigorously before removing
//void *gles2_lib = dlopen(NULL, RTLD_LAZY);
//glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE");
Expand Down
2 changes: 2 additions & 0 deletions drivers/unix/os_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
// Don't compile this code at all to avoid undefined references.
// Actual virtual call goes to OS_JavaScript.
ERR_FAIL_V(ERR_BUG);
#elif defined(TVOS_ENABLED)
ERR_FAIL_V(ERR_CANT_FORK);
#else
if (p_blocking && r_pipe) {

Expand Down
71 changes: 70 additions & 1 deletion editor/editor_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,65 @@ Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
return ios_project_static_libs;
}

void EditorExportPlugin::add_tvos_framework(const String &p_path) {
tvos_frameworks.push_back(p_path);
}

void EditorExportPlugin::add_tvos_embedded_framework(const String &p_path) {
tvos_embedded_frameworks.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_frameworks() const {
return tvos_frameworks;
}

Vector<String> EditorExportPlugin::get_tvos_embedded_frameworks() const {
return tvos_embedded_frameworks;
}

void EditorExportPlugin::add_tvos_plist_content(const String &p_plist_content) {
tvos_plist_content += p_plist_content + "\n";
}

String EditorExportPlugin::get_tvos_plist_content() const {
return tvos_plist_content;
}

void EditorExportPlugin::add_tvos_linker_flags(const String &p_flags) {
if (tvos_linker_flags.length() > 0) {
tvos_linker_flags += ' ';
}
tvos_linker_flags += p_flags;
}

String EditorExportPlugin::get_tvos_linker_flags() const {
return tvos_linker_flags;
}

void EditorExportPlugin::add_tvos_bundle_file(const String &p_path) {
tvos_bundle_files.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_bundle_files() const {
return tvos_bundle_files;
}

void EditorExportPlugin::add_tvos_cpp_code(const String &p_code) {
tvos_cpp_code += p_code;
}

String EditorExportPlugin::get_tvos_cpp_code() const {
return tvos_cpp_code;
}

void EditorExportPlugin::add_tvos_project_static_lib(const String &p_path) {
tvos_project_static_libs.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_project_static_libs() const {
return tvos_project_static_libs;
}

void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const PoolVector<String> &p_features) {

if (get_script_instance()) {
Expand Down Expand Up @@ -622,14 +681,24 @@ void EditorExportPlugin::skip() {
void EditorExportPlugin::_bind_methods() {

ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags"), &EditorExportPlugin::add_shared_object);
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
// iOS specific methods
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework);
ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework);
ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content);
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags);
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
// tvOS specific methods
ClassDB::bind_method(D_METHOD("add_tvos_project_static_lib", "path"), &EditorExportPlugin::add_tvos_project_static_lib);
ClassDB::bind_method(D_METHOD("add_tvos_framework", "path"), &EditorExportPlugin::add_tvos_framework);
ClassDB::bind_method(D_METHOD("add_tvos_embedded_framework", "path"), &EditorExportPlugin::add_tvos_embedded_framework);
ClassDB::bind_method(D_METHOD("add_tvos_plist_content", "plist_content"), &EditorExportPlugin::add_tvos_plist_content);
ClassDB::bind_method(D_METHOD("add_tvos_linker_flags", "flags"), &EditorExportPlugin::add_tvos_linker_flags);
ClassDB::bind_method(D_METHOD("add_tvos_bundle_file", "path"), &EditorExportPlugin::add_tvos_bundle_file);
ClassDB::bind_method(D_METHOD("add_tvos_cpp_code", "code"), &EditorExportPlugin::add_tvos_cpp_code);

ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);

BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::POOL_STRING_ARRAY, "features")));
Expand Down
31 changes: 31 additions & 0 deletions editor/editor_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,14 @@ class EditorExportPlugin : public Reference {
Vector<String> ios_bundle_files;
String ios_cpp_code;

Vector<String> tvos_frameworks;
Vector<String> tvos_embedded_frameworks;
Vector<String> tvos_project_static_libs;
String tvos_plist_content;
String tvos_linker_flags;
Vector<String> tvos_bundle_files;
String tvos_cpp_code;

_FORCE_INLINE_ void _clear() {
shared_objects.clear();
extra_files.clear();
Expand All @@ -307,6 +315,13 @@ class EditorExportPlugin : public Reference {
ios_plist_content = "";
ios_linker_flags = "";
ios_cpp_code = "";

tvos_frameworks.clear();
tvos_embedded_frameworks.clear();
tvos_bundle_files.clear();
tvos_plist_content = "";
tvos_linker_flags = "";
tvos_cpp_code = "";
}

void _export_file_script(const String &p_path, const String &p_type, const PoolVector<String> &p_features);
Expand All @@ -328,6 +343,14 @@ class EditorExportPlugin : public Reference {
void add_ios_bundle_file(const String &p_path);
void add_ios_cpp_code(const String &p_code);

void add_tvos_framework(const String &p_path);
void add_tvos_embedded_framework(const String &p_path);
void add_tvos_project_static_lib(const String &p_path);
void add_tvos_plist_content(const String &p_plist_content);
void add_tvos_linker_flags(const String &p_flags);
void add_tvos_bundle_file(const String &p_path);
void add_tvos_cpp_code(const String &p_code);

void skip();

virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
Expand All @@ -344,6 +367,14 @@ class EditorExportPlugin : public Reference {
Vector<String> get_ios_bundle_files() const;
String get_ios_cpp_code() const;

Vector<String> get_tvos_frameworks() const;
Vector<String> get_tvos_embedded_frameworks() const;
Vector<String> get_tvos_project_static_libs() const;
String get_tvos_plist_content() const;
String get_tvos_linker_flags() const;
Vector<String> get_tvos_bundle_files() const;
String get_tvos_cpp_code() const;

EditorExportPlugin();
};

Expand Down
1 change: 1 addition & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph

GLOBAL_DEF("display/window/ios/hide_home_indicator", true);
GLOBAL_DEF("input_devices/pointing/ios/touch_delay", 0.150);
GLOBAL_DEF("input_devices/pointing/tvos/press_end_delay", 0.150);

Engine::get_singleton()->set_frame_delay(frame_delay);

Expand Down
1 change: 1 addition & 0 deletions main/main_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def make_default_controller_mappings(target, source, env):
"Mac OS X": "#ifdef OSX_ENABLED",
"Android": "#if defined(__ANDROID__)",
"iOS": "#ifdef IPHONE_ENABLED",
"tvOS": "#ifdef TVOS_ENABLED",
"Javascript": "#ifdef JAVASCRIPT_ENABLED",
"UWP": "#ifdef UWP_ENABLED",
}
Expand Down
Loading