Skip to content

Commit

Permalink
Prototype for using starboard as an ozone platform (#4655)
Browse files Browse the repository at this point in the history
b/371272304
  • Loading branch information
TyHolc authored Jan 7, 2025
1 parent ec08539 commit 048f214
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 26 deletions.
3 changes: 2 additions & 1 deletion cobalt/cobalt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ int main(int argc, const char** argv) {
"--single-process",
// Disable Vulkan.
"--disable-features=Vulkan",
// TODO(mcasas): Add "--ozone-platform=starboard".
// Force some ozone settings.
"--ozone-platform=starboard", "--use-gl=egl",
// Enable remote Devtools access.
"--remote-debugging-port=9222",
"--remote-allow-origins=http://localhost:9222",
Expand Down
21 changes: 12 additions & 9 deletions gpu/config/gpu_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,9 @@ GpuFeatureStatus GetGLFeatureStatus(const std::set<int>& blocklisted_features,
// path on top of SwiftShader driver.
return kGpuFeatureStatusEnabled;
}
if (blocklisted_features.count(GPU_FEATURE_TYPE_ACCELERATED_GL))
return kGpuFeatureStatusBlocklisted;
// TODO(cobalt, b/371272304): Re-enable
// if (blocklisted_features.count(GPU_FEATURE_TYPE_ACCELERATED_GL))
// return kGpuFeatureStatusBlocklisted;
return kGpuFeatureStatusEnabled;
}

Expand Down Expand Up @@ -816,13 +817,15 @@ bool EnableSwiftShaderIfNeeded(base::CommandLine* command_line,
// Don't overwrite user preference.
if (command_line->HasSwitch(switches::kUseGL))
return false;
if (gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL] !=
kGpuFeatureStatusEnabled ||
gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_GL] !=
kGpuFeatureStatusEnabled) {
gl::SetSoftwareWebGLCommandLineSwitches(command_line);
return true;
}
// TODO(cobalt, b/371272304): Re-enable
// if (gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL] !=
// kGpuFeatureStatusEnabled ||
// gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_GL] !=
// kGpuFeatureStatusEnabled) {
// LOG(INFO) << "Enabling Swiftshader (BAD)";
// gl::SetSoftwareWebGLCommandLineSwitches(command_line);
// return true;
// }
return false;
#else
return false;
Expand Down
3 changes: 2 additions & 1 deletion starboard/shared/linux/system_network_status.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ bool GetOnlineStatus(bool* is_online_ptr, int netlink_fd) {
sa.nl_groups = RTMGRP_IPV4_IFADDR;
sa.nl_pid = getpid();
int bind_result = bind(netlink_fd, (struct sockaddr*)&sa, sizeof(sa));
SB_DCHECK(bind_result == 0);
// TODO(cobalt, b/371272304): Re-enable
// SB_DCHECK(bind_result == 0);

char buf[8192];
struct iovec iov;
Expand Down
3 changes: 3 additions & 0 deletions ui/ozone/platform/starboard/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ source_set("starboard") {
"gl_ozone_egl_starboard.h",
"ozone_platform_starboard.cc",
"ozone_platform_starboard.h",
"platform_event_source_starboard.cc",
"platform_event_source_starboard.h",
"platform_screen_starboard.cc",
"platform_screen_starboard.h",
"platform_window_starboard.cc",
Expand All @@ -40,6 +42,7 @@ source_set("starboard") {
"//ui/base/ime",
"//ui/display",
"//ui/display/fake",
"//ui/events/ozone/layout:layout",
"//ui/gfx:native_widget_types",
"//ui/ozone:ozone_base",
"//ui/ozone/common",
Expand Down
46 changes: 33 additions & 13 deletions ui/ozone/platform/starboard/ozone_platform_starboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@

#include "ui/ozone/platform/starboard/ozone_platform_starboard.h"

#include <thread>

#include "base/logging.h"
#include "starboard/event.h"
#include "ui/base/ime/input_method_minimal.h"
#include "ui/display/fake/fake_display_delegate.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#include "ui/gl/gl_switches.h"
#include "ui/ozone/common/bitmap_cursor_factory.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/starboard/platform_event_source_starboard.h"
#include "ui/ozone/platform/starboard/platform_screen_starboard.h"
#include "ui/ozone/platform/starboard/platform_window_starboard.h"
#include "ui/ozone/platform/starboard/surface_factory_starboard.h"
Expand Down Expand Up @@ -105,7 +111,31 @@ class OzonePlatformStarboard : public OzonePlatform {
return std::make_unique<InputMethodMinimal>(ime_key_event_dispatcher);
}

void PostCreateMainMessageLoop(base::OnceCallback<void()> shutdown_cb,
scoped_refptr<base::SingleThreadTaskRunner>
user_input_task_runner) override {}

bool InitializeUI(const InitParams& params) override {
if (!surface_factory_) {
surface_factory_ = std::make_unique<SurfaceFactoryStarboard>();
}
// Not thread safe. This is just for prototyping.
platform_event_source_ =
std::make_unique<starboard::PlatformEventSourceStarboard>();
keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
keyboard_layout_engine_.get());

// TODO(b/371272304): Investigate if we need our own implementation of
// OverlayManager.
// It doesn't matter which of the UI or GPU creates | overlay_manager_ | and
// | surface_factory_ | in single-process mode.
if (!overlay_manager_) {
overlay_manager_ = std::make_unique<StubOverlayManager>();
}
// TODO(b/371272304): Investigate if we need our own implementation of
// InputController for things like gamepads or other atypical input devices.
input_controller_ = CreateStubInputController();
// TODO(b/371272304): Investigate if we need a more robust cursor factory or
// if we can continue using BitmapCursorFactory.
cursor_factory_ = std::make_unique<BitmapCursorFactory>();
Expand All @@ -114,19 +144,6 @@ class OzonePlatformStarboard : public OzonePlatform {
// single process, investigate if this is needed or if there's any
// additional features we might need to implement from there.
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
// TODO(b/371272304): Investigate if we need our own implementation of
// InputController for things like gamepads or other atypical input devices.
input_controller_ = CreateStubInputController();
// TODO(b/371272304): Investigate if we need our own implementation of
// OverlayManager.
// It doesn't matter which of the UI or GPU creates | overlay_manager_ | and
// | surface_factory_ | in single-process mode.
if (!overlay_manager_) {
overlay_manager_ = std::make_unique<StubOverlayManager>();
}
if (!surface_factory_) {
surface_factory_ = std::make_unique<SurfaceFactoryStarboard>();
}

return true;
}
Expand All @@ -143,10 +160,13 @@ class OzonePlatformStarboard : public OzonePlatform {
}

private:
std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
std::unique_ptr<CursorFactory> cursor_factory_;
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
std::unique_ptr<InputController> input_controller_;
std::unique_ptr<OverlayManagerOzone> overlay_manager_;
std::unique_ptr<starboard::PlatformEventSourceStarboard>
platform_event_source_;
std::unique_ptr<SurfaceFactoryStarboard> surface_factory_;
};

Expand Down
190 changes: 190 additions & 0 deletions ui/ozone/platform/starboard/platform_event_source_starboard.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
// Copyright 2024 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "ui/ozone/platform/starboard/platform_event_source_starboard.h"

#include "base/logging.h"
#include "starboard/event.h"
#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/log.h"
#include "ui/events/event.h"

#include "base/containers/fixed_flat_map.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"

#include "ui/events/types/event_type.h"

namespace starboard {

constexpr auto kSbKeyToDomCodeMap = base::MakeFixedFlatMap<SbKey, ui::DomCode>({
// Convenience keys for keyboard support.
{kSbKeySpace, ui::DomCode::MEDIA_PLAY_PAUSE},

// Keys which are used by the Cast SDK.
{kSbKeyReturn, ui::DomCode::ENTER},
{kSbKeySelect, ui::DomCode::SELECT},
{kSbKeyUp, ui::DomCode::ARROW_UP},
{kSbKeyDown, ui::DomCode::ARROW_DOWN},
{kSbKeyLeft, ui::DomCode::ARROW_LEFT},
{kSbKeyRight, ui::DomCode::ARROW_RIGHT},
{kSbKeyBack, ui::DomCode::BROWSER_BACK},

// Keys which are used by the Cast SDK when the DPAD UI is enabled.
{kSbKeyMediaPlayPause, ui::DomCode::MEDIA_PLAY_PAUSE},
{kSbKeyMediaRewind, ui::DomCode::MEDIA_REWIND},
{kSbKeyMediaFastForward, ui::DomCode::MEDIA_FAST_FORWARD},
{kSbKeyMediaNextTrack, ui::DomCode::MEDIA_TRACK_NEXT},
{kSbKeyMediaPrevTrack, ui::DomCode::MEDIA_TRACK_PREVIOUS},
{kSbKeyPause, ui::DomCode::MEDIA_PAUSE},
{kSbKeyPlay, ui::DomCode::MEDIA_PLAY},
{kSbKeyMediaStop, ui::DomCode::MEDIA_STOP},

// Keys which are not used by the Cast SDK, but are defined in the HDMI
// CEC specification.
{kSbKeyMenu, ui::DomCode::HOME},
{kSbKeyChannelUp, ui::DomCode::CHANNEL_UP},
{kSbKeyChannelDown, ui::DomCode::CHANNEL_DOWN},
{kSbKeyClosedCaption, ui::DomCode::CLOSED_CAPTION_TOGGLE},
{kSbKeyRecord, ui::DomCode::MEDIA_RECORD},
});
// Hack: replace this when implementing event handling
static scoped_refptr<base::TaskRunner> g_reply_runner_;

void DeliverEventHandler(std::unique_ptr<ui::Event> ui_event) {
CHECK(ui::PlatformEventSource::GetInstance());
static_cast<PlatformEventSourceStarboard*>(
ui::PlatformEventSource::GetInstance())
->DeliverEvent(std::move(ui_event));
}

void PlatformEventSourceStarboard::SbEventHandle(const SbEvent* event) {
if (event->type != kSbEventTypeInput) {
return;
}

if (event->data == nullptr) {
return;
}
auto* input_data = static_cast<SbInputData*>(event->data);

int64_t raw_timestamp = event->timestamp;
SbInputEventType raw_type = input_data->type;

std::string type_name;
switch (input_data->type) {
case kSbInputEventTypeMove:
type_name = "kSbInputEventTypeMove";
break;
case kSbInputEventTypePress:
type_name = "kSbInputEventTypePress";
break;
case kSbInputEventTypeUnpress:
type_name = "kSbInputEventTypeUnpress";
break;
case kSbInputEventTypeWheel:
type_name = "kSbInputEventTypeWheel";
break;
case kSbInputEventTypeInput:
type_name = "kSbInputEventTypeInput";
break;
}

std::unique_ptr<ui::Event> ui_event;

if (input_data->device_type == kSbInputDeviceTypeKeyboard) {
SbKey raw_key = input_data->key;
if (raw_type != kSbInputEventTypePress &&
raw_type != kSbInputEventTypeUnpress) {
return;
}

auto it = kSbKeyToDomCodeMap.find(raw_key);
if (it == kSbKeyToDomCodeMap.end()) {
return;
}

ui::DomKey dom_key;
ui::KeyboardCode key_code;
ui::DomCode dom_code = it->second;

int flags = 0;
if (!DomCodeToUsLayoutDomKey(dom_code, flags, &dom_key, &key_code)) {
return;
}

// Key press.
ui::EventType event_type = raw_type == kSbInputEventTypePress
? ui::EventType::ET_KEY_PRESSED
: ui::EventType::ET_KEY_RELEASED;
ui_event = std::make_unique<ui::KeyEvent>(
event_type, key_code, dom_code, flags, dom_key,
/*time_stamp=*/
base::TimeTicks() + base::Microseconds(raw_timestamp));
} else if (input_data->device_type == kSbInputDeviceTypeMouse) {
ui::EventType event_type = ui::EventType::ET_UNKNOWN;
switch (input_data->type) {
case kSbInputEventTypeMove:
event_type = ui::EventType::ET_MOUSE_MOVED;
break;
case kSbInputEventTypePress:
event_type = ui::EventType::ET_MOUSE_PRESSED;
break;
case kSbInputEventTypeUnpress:
event_type = ui::EventType::ET_MOUSE_RELEASED;
break;
case kSbInputEventTypeWheel:
event_type = ui::EventType::ET_MOUSEWHEEL;
break;
case kSbInputEventTypeInput:
break;
}
int flag = ui::EF_NONE;
if (kSbInputEventTypePress) {
flag = ui::EF_LEFT_MOUSE_BUTTON;
}

// Mouse wheel scrolls are separate from MouseEvent and will crash here. We
// need to handle them properly.
if (event_type == ui::EventType::ET_MOUSEWHEEL) {
return;
}
ui_event = std::make_unique<ui::MouseEvent>(
event_type, gfx::PointF(input_data->position.x, input_data->position.y),
gfx::PointF{}, base::TimeTicks() + base::Microseconds(raw_timestamp),
flag, ui::EF_LEFT_MOUSE_BUTTON);
} else {
return;
}

g_reply_runner_->PostTask(
FROM_HERE, base::BindOnce(&DeliverEventHandler, std::move(ui_event)));
}

PlatformEventSourceStarboard::PlatformEventSourceStarboard() {
sb_main_ = std::make_unique<std::thread>(&SbRunStarboardMain, /*argc=*/0,
/*argv=*/nullptr, &SbEventHandle);
g_reply_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault();
sb_main_->detach();
}

uint32_t PlatformEventSourceStarboard::DeliverEvent(
std::unique_ptr<ui::Event> ui_event) {
return DispatchEvent(ui_event.get());
}

PlatformEventSourceStarboard::~PlatformEventSourceStarboard() {}
} // namespace starboard
47 changes: 47 additions & 0 deletions ui/ozone/platform/starboard/platform_event_source_starboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2024 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_
#define UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_

#include "ui/events/platform/platform_event_source.h"

#include "base/task/single_thread_task_runner.h"
#include "starboard/event.h"

#include <thread>

namespace starboard {

class PlatformEventSourceStarboard : public ui::PlatformEventSource {
public:
PlatformEventSourceStarboard();

PlatformEventSourceStarboard(const PlatformEventSourceStarboard&) = delete;
PlatformEventSourceStarboard& operator=(const PlatformEventSourceStarboard&) =
delete;

~PlatformEventSourceStarboard() override;

static void SbEventHandle(const SbEvent* event);

uint32_t DeliverEvent(std::unique_ptr<ui::Event> ui_event);

private:
std::unique_ptr<std::thread> sb_main_;
};

} // namespace starboard

#endif // UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_
Loading

0 comments on commit 048f214

Please sign in to comment.