diff --git a/cobalt/cobalt.cc b/cobalt/cobalt.cc index 877226e4f6e9..32f64c9ea689 100644 --- a/cobalt/cobalt.cc +++ b/cobalt/cobalt.cc @@ -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", diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc index 3eaebb76e9e9..15a352c95d9f 100644 --- a/gpu/config/gpu_util.cc +++ b/gpu/config/gpu_util.cc @@ -289,8 +289,9 @@ GpuFeatureStatus GetGLFeatureStatus(const std::set& 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; } @@ -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; diff --git a/starboard/shared/linux/system_network_status.cc b/starboard/shared/linux/system_network_status.cc index 8cc6c8cf97af..343de60332a2 100644 --- a/starboard/shared/linux/system_network_status.cc +++ b/starboard/shared/linux/system_network_status.cc @@ -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; diff --git a/ui/ozone/platform/starboard/BUILD.gn b/ui/ozone/platform/starboard/BUILD.gn index 829c1cd804bb..27cb68f84ea1 100644 --- a/ui/ozone/platform/starboard/BUILD.gn +++ b/ui/ozone/platform/starboard/BUILD.gn @@ -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", @@ -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", diff --git a/ui/ozone/platform/starboard/ozone_platform_starboard.cc b/ui/ozone/platform/starboard/ozone_platform_starboard.cc index 34d19235ac7c..c5d644be0932 100644 --- a/ui/ozone/platform/starboard/ozone_platform_starboard.cc +++ b/ui/ozone/platform/starboard/ozone_platform_starboard.cc @@ -14,12 +14,18 @@ #include "ui/ozone/platform/starboard/ozone_platform_starboard.h" +#include + #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" @@ -105,7 +111,31 @@ class OzonePlatformStarboard : public OzonePlatform { return std::make_unique(ime_key_event_dispatcher); } + void PostCreateMainMessageLoop(base::OnceCallback shutdown_cb, + scoped_refptr + user_input_task_runner) override {} + bool InitializeUI(const InitParams& params) override { + if (!surface_factory_) { + surface_factory_ = std::make_unique(); + } + // Not thread safe. This is just for prototyping. + platform_event_source_ = + std::make_unique(); + keyboard_layout_engine_ = std::make_unique(); + 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(); + } + // 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(); @@ -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(); - } - if (!surface_factory_) { - surface_factory_ = std::make_unique(); - } return true; } @@ -143,10 +160,13 @@ class OzonePlatformStarboard : public OzonePlatform { } private: + std::unique_ptr keyboard_layout_engine_; std::unique_ptr cursor_factory_; std::unique_ptr gpu_platform_support_host_; std::unique_ptr input_controller_; std::unique_ptr overlay_manager_; + std::unique_ptr + platform_event_source_; std::unique_ptr surface_factory_; }; diff --git a/ui/ozone/platform/starboard/platform_event_source_starboard.cc b/ui/ozone/platform/starboard/platform_event_source_starboard.cc new file mode 100644 index 000000000000..2d8bb94dfaaa --- /dev/null +++ b/ui/ozone/platform/starboard/platform_event_source_starboard.cc @@ -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({ + // 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 g_reply_runner_; + +void DeliverEventHandler(std::unique_ptr ui_event) { + CHECK(ui::PlatformEventSource::GetInstance()); + static_cast( + 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(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; + + 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( + 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( + 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(&SbRunStarboardMain, /*argc=*/0, + /*argv=*/nullptr, &SbEventHandle); + g_reply_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault(); + sb_main_->detach(); +} + +uint32_t PlatformEventSourceStarboard::DeliverEvent( + std::unique_ptr ui_event) { + return DispatchEvent(ui_event.get()); +} + +PlatformEventSourceStarboard::~PlatformEventSourceStarboard() {} +} // namespace starboard diff --git a/ui/ozone/platform/starboard/platform_event_source_starboard.h b/ui/ozone/platform/starboard/platform_event_source_starboard.h new file mode 100644 index 000000000000..afe6526588d4 --- /dev/null +++ b/ui/ozone/platform/starboard/platform_event_source_starboard.h @@ -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 + +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); + + private: + std::unique_ptr sb_main_; +}; + +} // namespace starboard + +#endif // UI_OZONE_PLATFORM_STARBOARD_STARBOARD_PLATFORM_EVENT_SOURCE_H_ diff --git a/ui/ozone/platform/starboard/platform_screen_starboard.cc b/ui/ozone/platform/starboard/platform_screen_starboard.cc index e4b6012a4650..880965e57cd6 100644 --- a/ui/ozone/platform/starboard/platform_screen_starboard.cc +++ b/ui/ozone/platform/starboard/platform_screen_starboard.cc @@ -65,10 +65,12 @@ PlatformScreenStarboard::GetAcceleratedWidgetAtScreenPoint( void PlatformScreenStarboard::AddObserver(display::DisplayObserver* observer) { // TODO(b/371272304): Add Observer to display::DisplayList. + display_list_.AddObserver(observer); } void PlatformScreenStarboard::RemoveObserver( display::DisplayObserver* observer) { // TODO(b/371272304): Remove Observer from display::DisplayList. + display_list_.RemoveObserver(observer); } } // namespace ui diff --git a/ui/ozone/platform/starboard/platform_window_starboard.cc b/ui/ozone/platform/starboard/platform_window_starboard.cc index 1b8b8cb4cf59..3d766d68266d 100644 --- a/ui/ozone/platform/starboard/platform_window_starboard.cc +++ b/ui/ozone/platform/starboard/platform_window_starboard.cc @@ -14,6 +14,10 @@ #include "ui/ozone/platform/starboard/platform_window_starboard.h" +#include "base/functional/bind.h" +#include "ui/events/event.h" +#include "ui/events/ozone/events_ozone.h" +#include "ui/events/platform/platform_event_source.h" #include "ui/gfx/native_widget_types.h" namespace ui { @@ -24,8 +28,28 @@ PlatformWindowStarboard::PlatformWindowStarboard( : StubWindow(delegate, /*use_default_accelerated_widget=*/false, bounds) { gfx::AcceleratedWidget widget = (bounds.width() << 16) + bounds.height(); delegate->OnAcceleratedWidgetAvailable(widget); + + if (PlatformEventSource::GetInstance()) { + PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); + } +} + +PlatformWindowStarboard::~PlatformWindowStarboard() { + if (PlatformEventSource::GetInstance()) { + PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); + } } -PlatformWindowStarboard::~PlatformWindowStarboard() {} +bool PlatformWindowStarboard::CanDispatchEvent(const PlatformEvent& event) { + return true; +} + +uint32_t PlatformWindowStarboard::DispatchEvent(const PlatformEvent& event) { + DispatchEventFromNativeUiEvent( + event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent, + base::Unretained(delegate()))); + + return ui::POST_DISPATCH_STOP_PROPAGATION; +} } // namespace ui diff --git a/ui/ozone/platform/starboard/platform_window_starboard.h b/ui/ozone/platform/starboard/platform_window_starboard.h index 0d45665e74e0..1cc81700b65f 100644 --- a/ui/ozone/platform/starboard/platform_window_starboard.h +++ b/ui/ozone/platform/starboard/platform_window_starboard.h @@ -15,6 +15,7 @@ #ifndef UI_OZONE_PLATFORM_STARBOARD_PLATFORM_WINDOW_STARBOARD_H_ #define UI_OZONE_PLATFORM_STARBOARD_PLATFORM_WINDOW_STARBOARD_H_ +#include "ui/events/platform/platform_event_dispatcher.h" #include "ui/platform_window/platform_window_delegate.h" #include "ui/platform_window/stub/stub_window.h" @@ -23,7 +24,8 @@ namespace ui { // TODO(b/371272304): Stop extending StubWindow and create a more robust window // implementation. // TODO(b/371272304): Add event handling (i.e. extend PlatformEventDispatcher). -class PlatformWindowStarboard : public StubWindow { +class PlatformWindowStarboard : public StubWindow, + public PlatformEventDispatcher { public: PlatformWindowStarboard(PlatformWindowDelegate* delegate, const gfx::Rect& bounds); @@ -32,6 +34,9 @@ class PlatformWindowStarboard : public StubWindow { PlatformWindowStarboard& operator=(const PlatformWindowStarboard&) = delete; ~PlatformWindowStarboard() override; + + bool CanDispatchEvent(const PlatformEvent& event) override; + uint32_t DispatchEvent(const PlatformEvent& event) override; }; } // namespace ui