Skip to content
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

[Ozone] Move ownership of SbWindow to the platform window class #4688

Open
wants to merge 2 commits into
base: experimental/ozone
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion cobalt/cobalt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ int main(int argc, const char** argv) {
content::ContentMainParams params(&delegate);

// TODO: (cobalt b/375241103) Reimplement this in a clean way.

constexpr auto cobalt_args = std::to_array<const char*>(
{// Disable first run experience, kiosk, etc.
"--disable-fre", "--no-first-run", "--kiosk",
Expand All @@ -39,6 +38,8 @@ int main(int argc, const char** argv) {
"--disable-features=Vulkan",
// Force some ozone settings.
"--ozone-platform=starboard", "--use-gl=egl",
// Set the default size for the content shell/starboard window.
"--content-shell-host-window-size=1920x1080",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose an arbitrary size here for now, but I was thinking we could create a default SbOptions object and get the height and width from that if we wanted to initialize to those. Lmk thoughts on that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Leaving that Q for @y4vor )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the existing SbWindowGetSize.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is running before the starboard window is created, and will actually inform the initial size of the starboard window once it's created.

Because this will propagate to the SbWindow, I thought we could do something like:

SbWindowOptions options{};
SbWindowSetDefaultOptions(&options);
std::string window_size = options.size.width + "x" + options.size.height;

...
"--content-shell-host-window-size=" + window_size,
...

// Enable remote Devtools access.
"--remote-debugging-port=9222",
"--remote-allow-origins=http://localhost:9222",
Expand Down
14 changes: 13 additions & 1 deletion ui/ozone/platform/starboard/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,24 @@ source_set("starboard_unittests") {

testonly = true

sources = [ "test/surface_factory_starboard_unittest.cc" ]
sources = [
"test/platform_window_starboard_unittest.cc",
"test/starboard_test_helper.cc",
"test/starboard_test_helper.h",
"test/surface_factory_starboard_unittest.cc",
]

deps = [
":starboard",
"//starboard:starboard_headers_only",
"//starboard/common:common",
"//testing/gmock",
"//testing/gtest",
"//ui/events:events",
"//ui/events:events_base",
"//ui/events/types:headers",
"//ui/gl",
"//ui/platform_window:platform_window",
]
}

Expand Down
28 changes: 6 additions & 22 deletions ui/ozone/platform/starboard/gl_ozone_egl_starboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,29 @@ namespace ui {

GLOzoneEGLStarboard::GLOzoneEGLStarboard() = default;

GLOzoneEGLStarboard::~GLOzoneEGLStarboard() {
if (sb_window_) {
SbWindowDestroy(sb_window_);
}
}
GLOzoneEGLStarboard::~GLOzoneEGLStarboard() = default;

scoped_refptr<gl::GLSurface> GLOzoneEGLStarboard::CreateViewGLSurface(
gl::GLDisplay* display,
gfx::AcceleratedWidget window) {
CHECK(window != gfx::kNullAcceleratedWidget);
// TODO(b/371272304): Verify widget dimensions match our expected display size
// (likely full screen for Cobalt).
return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGL(
display->GetAs<gl::GLDisplayEGL>(), GetNativeWindow(),
display->GetAs<gl::GLDisplayEGL>(), window,
std::make_unique<gfx::FixedVSyncProvider>(base::TimeTicks(),
GetVSyncInterval())));
}

scoped_refptr<gl::GLSurface> GLOzoneEGLStarboard::CreateOffscreenGLSurface(
gl::GLDisplay* display,
const gfx::Size& size) {
return gl::InitializeGLSurface(
new gl::PbufferGLSurfaceEGL(display->GetAs<gl::GLDisplayEGL>(), size));
}

intptr_t GLOzoneEGLStarboard::GetNativeWindow() {
CreateDisplayTypeAndWindowIfNeeded();
return reinterpret_cast<intptr_t>(window_);
}

gl::EGLDisplayPlatform GLOzoneEGLStarboard::GetNativeDisplay() {
CreateDisplayTypeAndWindowIfNeeded();
CreateDisplayTypeIfNeeded();
return gl::EGLDisplayPlatform(
reinterpret_cast<EGLNativeDisplayType>(display_type_));
}
Expand All @@ -83,21 +76,12 @@ bool GLOzoneEGLStarboard::LoadGLES2Bindings(
return true;
}

void GLOzoneEGLStarboard::CreateDisplayTypeAndWindowIfNeeded() {
void GLOzoneEGLStarboard::CreateDisplayTypeIfNeeded() {
// TODO(b/371272304): Initialize hardware here if needed.
if (!have_display_type_) {
display_type_ = reinterpret_cast<void*>(SB_EGL_DEFAULT_DISPLAY);
have_display_type_ = true;
}
if (!window_) {
SbWindowOptions options{};
SbWindowSetDefaultOptions(&options);

sb_window_ = SbWindowCreate(&options);
window_ = SbWindowGetPlatformHandle(sb_window_);
}

CHECK(window_);
}

} // namespace ui
6 changes: 1 addition & 5 deletions ui/ozone/platform/starboard/gl_ozone_egl_starboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#ifndef UI_OZONE_PLATFORM_STARBOARD_GL_OZONE_EGL_STARBOARD_H_
#define UI_OZONE_PLATFORM_STARBOARD_GL_OZONE_EGL_STARBOARD_H_

#include "starboard/window.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/common/gl_ozone_egl.h"

Expand All @@ -36,19 +35,16 @@ class GLOzoneEGLStarboard : public GLOzoneEGL {
gl::GLDisplay* display,
const gfx::Size& size) override;

intptr_t GetNativeWindow();

protected:
gl::EGLDisplayPlatform GetNativeDisplay() override;
bool LoadGLES2Bindings(
const gl::GLImplementationParts& implementation) override;

private:
void CreateDisplayTypeAndWindowIfNeeded();
void CreateDisplayTypeIfNeeded();

void* display_type_ = nullptr;
bool have_display_type_ = false;
SbWindow sb_window_;
void* window_ = nullptr;
};

Expand Down
15 changes: 13 additions & 2 deletions ui/ozone/platform/starboard/platform_window_starboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,26 @@ PlatformWindowStarboard::PlatformWindowStarboard(
PlatformWindowDelegate* delegate,
const gfx::Rect& bounds)
: StubWindow(delegate, /*use_default_accelerated_widget=*/false, bounds) {
gfx::AcceleratedWidget widget = (bounds.width() << 16) + bounds.height();
delegate->OnAcceleratedWidgetAvailable(widget);
SbWindowOptions options{};
SbWindowSetDefaultOptions(&options);
options.size.width = bounds.width();
options.size.height = bounds.height();
sb_window_ = SbWindowCreate(&options);
CHECK(SbWindowIsValid(sb_window_));

delegate->OnAcceleratedWidgetAvailable(
reinterpret_cast<intptr_t>(SbWindowGetPlatformHandle(sb_window_)));

if (PlatformEventSource::GetInstance()) {
PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
}
}

PlatformWindowStarboard::~PlatformWindowStarboard() {
if (sb_window_) {
SbWindowDestroy(sb_window_);
}

if (PlatformEventSource::GetInstance()) {
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
Expand Down
4 changes: 4 additions & 0 deletions ui/ozone/platform/starboard/platform_window_starboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef UI_OZONE_PLATFORM_STARBOARD_PLATFORM_WINDOW_STARBOARD_H_
#define UI_OZONE_PLATFORM_STARBOARD_PLATFORM_WINDOW_STARBOARD_H_

#include "starboard/window.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"
Expand All @@ -37,6 +38,9 @@ class PlatformWindowStarboard : public StubWindow,

bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;

private:
SbWindow sb_window_;
};

} // namespace ui
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2025 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_window_starboard.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/types/event_type.h"
#include "ui/ozone/platform/starboard/test/starboard_test_helper.h"

namespace ui {
namespace {
// Using OzoneStarboardTest to allow SbWindowCreate and SbWindowDestroy.
class PlatformWindowStarboardTest : public OzoneStarboardTest {
public:
PlatformWindowStarboardTest() {
sb_window_ =
std::make_unique<PlatformWindowStarboard>(&delegate_, gfx::Rect(0, 0));
}

~PlatformWindowStarboardTest() {
// Reset |sb_window_| before parent destructor is called so SbWindowDestroy
// can run.
sb_window_.reset();
}

PlatformWindowStarboard* window() { return sb_window_.get(); }

protected:
MockPlatformWindowDelegate delegate_;

private:
// Using a pointer to delay initialization of the window until after starting
// the main Starboard thread in partent constructor.
std::unique_ptr<PlatformWindowStarboard> sb_window_;
};

TEST_F(PlatformWindowStarboardTest, CanDispatchEvent) {
ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
const PlatformEvent& platform_event = &event;

EXPECT_TRUE(window()->CanDispatchEvent(platform_event));
}

TEST_F(PlatformWindowStarboardTest, DispatchEvent) {
ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
const PlatformEvent& platform_event = &event;

ui::EventType type;
EXPECT_CALL(delegate_, DispatchEvent(testing::_))
.Times(1)
.WillOnce([&type](const PlatformEvent& event) {
type = ui::EventTypeFromNative(event);
});

auto result = window()->DispatchEvent(platform_event);
EXPECT_EQ(result, ui::POST_DISPATCH_STOP_PROPAGATION);
EXPECT_EQ(type, ui::ET_MOUSE_PRESSED);
}
} // namespace
} // namespace ui
73 changes: 73 additions & 0 deletions ui/ozone/platform/starboard/test/starboard_test_helper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2025 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/test/starboard_test_helper.h"

#include "starboard/system.h"

namespace ui {
// SbEventHandle needs to call into the test class' event handler to signal the
// |started_condition_|, so the test object is tracked here.
OzoneStarboardTest* ozone_starboard_test_instance = nullptr;

// Static callback for SbEvents. This will pass events to the test class'
// implementation of |EventHandleInternal| to signal the main thread has
// started.
void SbEventHandle(const SbEvent* event) {
if (ozone_starboard_test_instance) {
ozone_starboard_test_instance->EventHandleInternal(event);
}
}

OzoneStarboardTest::OzoneStarboardTest() {
ozone_starboard_test_instance = this;

started_condition_ = std::make_unique<ConditionVariable>(started_mutex_);

// Start the main starboard thread to allow Starboard function calls.
sb_main_ = std::make_unique<OzoneStarboardThread>();
started_mutex_.Acquire();
sb_main_->Start();
// Wait for the |kSbEventTypeStart| to signal the initialization completion
// before continuing.
started_condition_->Wait();
started_mutex_.Release();
}

OzoneStarboardTest::~OzoneStarboardTest() {
// Kill and clean up the Starboard main thread.
SbSystemRequestStop(0);
sb_main_->Join();
sb_main_.reset();

started_condition_.reset();
ozone_starboard_test_instance = nullptr;
}

// Note: If overriding this function, be sure to signal the started_condition_
// or the test will hang.
void OzoneStarboardTest::EventHandleInternal(const SbEvent* event) {
switch (event->type) {
case kSbEventTypeStart:
started_condition_->Signal();
break;
default:
break;
}
}

void OzoneStarboardTest::OzoneStarboardThread::Run() {
SbRunStarboardMain(0, nullptr, &SbEventHandle);
}
} // namespace ui
Loading
Loading