-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch can be cherry-picked to add Cast Starboard API support to `lts.23.1+`. The Cast Starboard API is a shared library which contains the portion of Starboard required to run Cast. This includes the following changes: - Add reference implementation, tests, and README.md into `starboard/contrib/cast` - Add `cast` to `//starboard:gn_all` - Fix a bug in ApplicationX11 which was preventing it from working in modular builds, depending on invocation
- Loading branch information
Showing
11 changed files
with
546 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
## Cast Starboard API | ||
|
||
The Cast Starboard API is a shared library which contains the portion of | ||
Starboard required to run Cast. | ||
|
||
### Customizations | ||
|
||
As of Starboard 14, there are public methods required for Cast that are not | ||
already exposed by `libstarboard_platform_group.so`. These methods are declared | ||
in the header `cast_starboard_api.h`, and a sample implementation is provided | ||
in `cast_starboard_api_impl.cc`. | ||
|
||
Cast also requires additional behavior be implemented behind the existing | ||
Starboard APIs. Reference the `Cast TV Integration Guide` for details. | ||
|
||
### Reference Implementation | ||
|
||
The `cast_starboard_api/samples/` directory contains the reference target | ||
`cast_starboard_api` which can be built when `use_contrib_cast=true` is | ||
specified. To generate the target: | ||
|
||
``` | ||
gn gen out/linux-x64x11_devel --args="target_platform=\"linux-x64x11\" use_contrib_cast=true build_type=\"devel\"" | ||
``` | ||
|
||
To build the target: | ||
|
||
``` | ||
ninja -C out/linux-x64x11_devel/ cast_starboard_api | ||
``` | ||
|
||
### Test Suite | ||
|
||
Tests for Cast-specific behaviors are not currently included in NPLB or YTS. | ||
|
||
A limited test suite, `cast_starboard_api_test`, is provided to ensure the | ||
standalone library can be initialized and a window surface can be created in the | ||
format required by Cast. To build the test suite: | ||
|
||
``` | ||
ninja -C out/linux-x64x11_devel/ cast_starboard_api_test | ||
``` | ||
|
||
To run the test suite: | ||
|
||
``` | ||
./out/linux-x64x11_devel/cast_starboard_api_test | ||
``` | ||
|
||
### Known Issues | ||
|
||
- When `build_type=\"devel\"`, some systems may SB_DCHECK in `NetworkNotifier`. | ||
- On some toolchains, `use_asan=false` may be required to build cleanly. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
declare_args() { | ||
# Includes `//starboard/contrib/cast/cast_starboard_api/samples:cast` into | ||
# `//starboard:gn_all`. | ||
use_contrib_cast = false | ||
} |
41 changes: 41 additions & 0 deletions
41
starboard/contrib/cast/cast_starboard_api/cast_starboard_api.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2022 Google LLC. All rights reserved. | ||
|
||
#ifndef STARBOARD_CAST_CAST_STARBOARD_API_CAST_STARBOARD_API_H_ | ||
#define STARBOARD_CAST_CAST_STARBOARD_API_CAST_STARBOARD_API_H_ | ||
|
||
#include <starboard/drm.h> | ||
#include <starboard/egl.h> | ||
#include <starboard/event.h> | ||
#include <starboard/gles.h> | ||
#include <starboard/media.h> | ||
#include <starboard/player.h> | ||
#include <starboard/window.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// Initializes the Starboard thread and event loop. After this function is | ||
// called, the Starboard APIs included above are expected to be available. | ||
// | ||
// Optional command line arguments are passed through |argc| and |argv|. | ||
// The |callback| is analogous to SbEventHandle and must receive SbEvents. | ||
// | ||
// Must be called prior to the other library functions. Not guaranteed to be | ||
// thread-safe; other library functions should not be called until this returns. | ||
SB_EXPORT int CastStarboardApiInitialize(int argc, | ||
char** argv, | ||
void (*callback)(const SbEvent*)); | ||
|
||
// Finalizes the library in the provided |context|. | ||
// | ||
// Must not be called prior to the other library functions. Not guaranteed to be | ||
// thread-safe; this function should not be called until all other library | ||
// functions have returned. | ||
SB_EXPORT void CastStarboardApiFinalize(); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif | ||
|
||
#endif // STARBOARD_CAST_CAST_STARBOARD_API_CAST_STARBOARD_API_H_ |
79 changes: 79 additions & 0 deletions
79
starboard/contrib/cast/cast_starboard_api/samples/BUILD.gn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Copyright 2022 Google LLC. All rights reserved. | ||
import("//starboard/contrib/cast/cast.gni") | ||
|
||
assert(use_contrib_cast) | ||
|
||
group("cast") { | ||
public_deps = [ ":cast_starboard_api" ] | ||
} | ||
|
||
_CAST_STARBOARD_API_SOURCES = [ | ||
"../cast_starboard_api.h", | ||
"cast_starboard_api_impl.cc", | ||
] | ||
|
||
if (final_executable_type == "shared_library") { | ||
# Sample implementation of cast_starboard_api which utilizes StarboardMain. | ||
# This implementation should work on any platform, but cannot currently be | ||
# used with test because of the way StarboardMain is defined (by redefining | ||
# `main` in the binary) | ||
target(final_executable_type, "cast_starboard_api") { | ||
sources = _CAST_STARBOARD_API_SOURCES | ||
deps = [ | ||
"//starboard", | ||
"//$starboard_path:starboard_platform" | ||
] | ||
ldflags = [ | ||
# Prevents unresolved symbols | ||
"-Wl,-z,defs", | ||
# This makes Sb*, kSb*, and CastStarboardApi* public, but they could still | ||
# be hidden by other compiler flags. | ||
"-Wl,--version-script=" + rebase_path("./cast_starboard_api.lds", | ||
root_build_dir) | ||
] | ||
} | ||
} else { | ||
# Sample implementation of cast_starboard_api which utilizes a platform- | ||
# specific implementation. It does not require a specific build | ||
# configuration and can be tested with the `cast_starboard_api_test_main`. | ||
shared_library("cast_starboard_api") { | ||
sources = _CAST_STARBOARD_API_SOURCES | ||
defines = [ "CAST_STARBOARD_API_X11"] | ||
deps = [ | ||
"//starboard", | ||
] | ||
ldflags = [ | ||
# Prevents unresolved symbols | ||
"-Wl,-z,defs", | ||
# This makes Sb*, kSb*, and CastStarboardApi* public, but they could still | ||
# be hidden by other compiler flags. | ||
"-Wl,--version-script=" + rebase_path("./cast_starboard_api.lds", | ||
root_build_dir) | ||
] | ||
} | ||
|
||
copy("cast_starboard_api_test_data") { | ||
install_content = true | ||
sources = ["$root_out_dir/libcast_starboard_api.so"] | ||
outputs = [ "$sb_static_contents_output_data_dir/{{source_file_part}}" ] | ||
deps = [ | ||
":cast_starboard_api" | ||
] | ||
} | ||
|
||
target(gtest_target_type, "cast_starboard_api_test") { | ||
testonly = true | ||
sources = [ | ||
"//starboard/common/test_main.cc", | ||
"cast_starboard_api_test.cc", | ||
] | ||
data_deps = [ | ||
":cast_starboard_api_test_data", | ||
] | ||
deps = [ | ||
"//starboard", | ||
"//testing/gtest", | ||
"//starboard/nplb/testdata/file_tests:nplb_file_tests_data", | ||
] | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
starboard/contrib/cast/cast_starboard_api/samples/cast_starboard_api.lds
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright 2022 Google LLC. All rights reserved. | ||
LIBCAST_STARBOARD_API { | ||
global: | ||
CastStarboardApi*; | ||
kSb*; | ||
Sb*; | ||
local: | ||
*; | ||
}; |
111 changes: 111 additions & 0 deletions
111
starboard/contrib/cast/cast_starboard_api/samples/cast_starboard_api_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright 2022 Google LLC. All rights reserved. | ||
|
||
#include "../cast_starboard_api.h" | ||
|
||
#include <memory> | ||
|
||
#include "starboard/common/condition_variable.h" | ||
#include "starboard/common/log.h" | ||
#include "starboard/common/mutex.h" | ||
#include "starboard/common/thread.h" | ||
#include "starboard/egl.h" | ||
#include "starboard/system.h" | ||
|
||
#ifdef CAST_STARBOARD_API_X11 | ||
#include <X11/Xlib.h> | ||
#include "starboard/shared/x11/application_x11.h" | ||
#endif // CAST_STARBOARD_API_X11 | ||
|
||
#ifndef CAST_STARBOARD_API_X11 | ||
extern "C" int StarboardMain(int argc, char** argv); | ||
#endif | ||
|
||
namespace { | ||
class CastStarboardApiThread : public starboard::Thread { | ||
public: | ||
CastStarboardApiThread() : starboard::Thread("cast_thread") {} | ||
|
||
void Run() override { | ||
#ifdef CAST_STARBOARD_API_X11 | ||
// In this sample implementation, setting up the application is | ||
// required for some APIs to function correctly. For example,` | ||
// SbWindowCreate will crash without an existing ApplicationX11. | ||
starboard::shared::starboard::CommandLine command_line(0, nullptr); | ||
app = std::make_unique<starboard::shared::x11::ApplicationX11>(); | ||
|
||
// This never returns until kSbEventTypeStop is sent to the application, | ||
// so it can act as the thread loop. | ||
app->Run(command_line); | ||
#else // CAST_STARBOARD_API_X11 | ||
// **NOTE:** Calling StarboardMain(...) here should be enough, without | ||
// needing any other content. Typically StarboardMain is redefined from | ||
// main in builds where `final_executable_type == "shared_library"`. | ||
StarboardMain(0, nullptr); | ||
#endif // CAST_STARBOARD_API_X11 | ||
} | ||
|
||
private: | ||
#ifdef CAST_STARBOARD_API_X11 | ||
std::unique_ptr<starboard::shared::x11::ApplicationX11> app; | ||
#endif // CAST_STARBOARD_API_X11 | ||
}; | ||
|
||
void (*g_callback)(const SbEvent*) = nullptr; | ||
starboard::Mutex g_started_mutex; | ||
std::unique_ptr<starboard::ConditionVariable> g_started_cond; | ||
std::unique_ptr<CastStarboardApiThread> g_thread; | ||
bool g_initialized = false; | ||
} // namespace | ||
|
||
int CastStarboardApiInitialize(int argc, | ||
char** argv, | ||
void (*callback)(const SbEvent*)) { | ||
SB_CHECK(!g_thread) << "CastStarboardApiInitialize may only be called once"; | ||
SB_CHECK(callback) << "Argument 'callback' must not be NULL"; | ||
|
||
// Events given to SbEventHandle will be forwarded to |callback|. | ||
g_callback = callback; | ||
|
||
// Create event for initialization completion. | ||
g_started_cond = | ||
std::make_unique<starboard::ConditionVariable>(g_started_mutex); | ||
|
||
// Create the main Starboard thread. | ||
g_thread = std::make_unique<CastStarboardApiThread>(); | ||
g_thread->Start(); | ||
|
||
// Watch event for initialation completion. | ||
g_started_mutex.Acquire(); | ||
g_started_cond->Wait(); | ||
g_started_mutex.Release(); | ||
|
||
return 0; | ||
} | ||
|
||
void CastStarboardApiFinalize() { | ||
SB_CHECK(g_thread) << "CastStarboardApiFinalize may only be called after " | ||
"CastStarboardApiInitialize"; | ||
|
||
// |g_thread| cannot join until its internal event loop stops. | ||
SbSystemRequestStop(0); | ||
g_thread->Join(); | ||
|
||
// The thread is stopped so it's safe to reset. | ||
g_initialized = false; | ||
g_thread.reset(); | ||
g_started_cond.reset(); | ||
g_callback = nullptr; | ||
} | ||
|
||
void SbEventHandle(const SbEvent* event) { | ||
SB_DCHECK(g_callback); | ||
// Signal that initialization is complete. | ||
if (event->type == kSbEventTypeStart) { | ||
g_started_cond->Signal(); | ||
g_initialized = true; | ||
} | ||
|
||
if (g_initialized) { | ||
g_callback(event); | ||
} | ||
} |
Oops, something went wrong.