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

Add initial support for OpenHarmony #293

Merged
merged 6 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- os: windows-latest
target: "aarch64-pc-windows-msvc"
rust: stable
- os: ubuntu-22.04
target: "aarch64-unknown-linux-ohos"
rust: stable
steps:
- uses: actions/checkout@v4
- name: Install deps on linux
Expand Down
6 changes: 3 additions & 3 deletions surfman/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ log = "0.4"
sparkle = { version = "0.1", optional = true }
osmesa-sys = { version = "0.1", optional = true }
rwh_05 = { package = "raw-window-handle", version = "0.5.2", features = ["std"], optional = true }
rwh_06 = { package = "raw-window-handle", version = "0.6", features = ["std"], optional = true }
rwh_06 = { package = "raw-window-handle", version = "0.6.2", features = ["std"], optional = true }

[dev-dependencies]
clap = "2"
Expand All @@ -61,11 +61,11 @@ mach2 = "0.4"
metal = "0.24"
objc = "0.2"

[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))'.dependencies.wayland-sys]
[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_env = "ohos"))))'.dependencies.wayland-sys]
version = "0.30"
features = ["client", "dlopen", "egl"]

[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android"))))'.dependencies.x11]
[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "android", target_env = "ohos"))))'.dependencies.x11]
version = "2.3.0"
features = ["xlib"]
optional = true
Expand Down
7 changes: 5 additions & 2 deletions surfman/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ fn main() {
cfg_aliases! {
// Platforms
android_platform: { target_os = "android" },
ohos_platform: { target_env = "ohos" },
web_platform: { all(target_family = "wasm", target_os = "unknown") },
macos_platform: { target_os = "macos" },
ios_platform: { target_os = "ios" },
windows_platform: { target_os = "windows" },
apple: { any(target_os = "ios", target_os = "macos") },
free_unix: { all(unix, not(apple), not(android_platform), not(target_os = "emscripten")) },
free_unix: { all(unix, not(apple), not(android_platform), not(target_os = "emscripten"), not(ohos_platform)) },

// Native displays.
x11_platform: { all(free_unix, feature = "sm-x11") },
Expand All @@ -36,11 +37,13 @@ fn main() {

let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_family = env::var("CARGO_CFG_TARGET_FAMILY").ok();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());

// Generate EGL bindings.
if target_os == "android"
|| (target_os == "windows" && cfg!(feature = "sm-angle"))
|| target_env == "ohos"
|| target_family.as_ref().map_or(false, |f| f == "unix")
{
let mut file = File::create(dest.join("egl_bindings.rs")).unwrap();
Expand All @@ -49,7 +52,7 @@ fn main() {
}

// Generate GL bindings.
if target_os == "android" {
if target_os == "android" || target_env == "ohos" {
let mut file = File::create(dest.join("gl_bindings.rs")).unwrap();
let registry = Registry::new(Api::Gles2, (3, 0), Profile::Core, Fallbacks::All, []);
registry.write_bindings(StructGenerator, &mut file).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions surfman/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ impl ContextAttributes {
}
}

#[cfg(target_os = "android")]
#[cfg(any(target_os = "android", target_env = "ohos"))]
pub(crate) fn current_context_uses_compatibility_profile(_gl: &Gl) -> bool {
false
}

#[cfg(not(target_os = "android"))]
#[cfg(not(any(target_os = "android", target_env = "ohos")))]
#[allow(dead_code)]
pub(crate) fn current_context_uses_compatibility_profile(gl: &Gl) -> bool {
unsafe {
Expand Down
5 changes: 3 additions & 2 deletions surfman/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ pub use crate::surface::{SurfaceAccess, SurfaceID, SurfaceInfo, SurfaceType, Sys

pub mod macros;

#[cfg(not(target_os = "android"))]
#[cfg(not(any(target_os = "android", target_env = "ohos")))]
pub(crate) use crate::gl::Gl;
#[cfg(target_os = "android")]
#[cfg(any(target_os = "android", target_env = "ohos"))]
pub(crate) use crate::gl::Gles2 as Gl;

mod gl_utils;
Expand All @@ -70,6 +70,7 @@ mod gl {

#[cfg(any(
target_os = "android",
target_env = "ohos",
all(target_os = "windows", feature = "sm-angle"),
unix
))]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// surfman/surfman/src/platform/android/ffi.rs
// surfman/surfman/src/platform/egl/android_ffi.rs

use std::os::raw::c_int;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
// surfman/surfman/src/platform/android/connection.rs
// surfman/surfman/src/platform/egl/connection.rs
//
//! A no-op connection for Android.
//!
//! FIXME(pcwalton): Should this instead wrap `EGLDisplay`? Is that thread-safe on Android?

use super::device::{Adapter, Device, NativeDevice};
use super::ffi::ANativeWindow;
use super::surface::NativeWidget;
use crate::Error;
use crate::GLApi;

#[cfg(android_platform)]
use super::android_ffi::ANativeWindow;
#[cfg(ohos_platform)]
use super::ohos_ffi::OHNativeWindow;

use euclid::default::Size2D;

use std::os::raw::c_void;
Expand Down Expand Up @@ -109,24 +113,34 @@ impl Connection {
Ok(Connection)
}

#[cfg(android_platform)]
fn create_native_widget_from_ptr_impl(raw: *mut c_void) -> NativeWidget {
NativeWidget {
native_window: raw as *mut ANativeWindow,
}
}

#[cfg(ohos_platform)]
fn create_native_widget_from_ptr_impl(raw: *mut c_void) -> NativeWidget {
NativeWidget {
native_window: raw as *mut OHNativeWindow,
}
}

/// Create a native widget from a raw pointer
pub unsafe fn create_native_widget_from_ptr(
&self,
raw: *mut c_void,
_size: Size2D<i32>,
) -> NativeWidget {
NativeWidget {
native_window: raw as *mut ANativeWindow,
}
debug_assert!(!raw.is_null());
Self::create_native_widget_from_ptr_impl(raw)
}

/// Create a native widget type from the given `RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle-05")]
#[cfg(all(feature = "sm-raw-window-handle-05", android_platform))]
#[inline]
pub fn create_native_widget_from_raw_window_handle(
&self,
fn create_native_widget_from_rwh_05_handle(
raw_handle: rwh_05::RawWindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
use rwh_05::RawWindowHandle::AndroidNdk;

Expand All @@ -138,13 +152,29 @@ impl Connection {
}
}

/// Create a native widget type from the given `WindowHandle`.
#[cfg(feature = "sm-raw-window-handle-06")]
#[cfg(all(feature = "sm-raw-window-handle-05", ohos_platform))]
#[inline]
pub fn create_native_widget_from_window_handle(
fn create_native_widget_from_rwh_05_handle(
_raw_handle: rwh_05::RawWindowHandle,
) -> Result<NativeWidget, Error> {
Err(Error::IncompatibleNativeWidget)
}

/// Create a native widget type from the given `RawWindowHandle`.
#[cfg(feature = "sm-raw-window-handle-05")]
#[inline]
pub fn create_native_widget_from_raw_window_handle(
&self,
handle: rwh_06::WindowHandle,
raw_handle: rwh_05::RawWindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
create_native_widget_from_rwh_05_handle(raw_handle)
}

#[cfg(all(feature = "sm-raw-window-handle-06", android_platform))]
#[inline]
fn create_native_widget_from_rwh_06_handle(
handle: rwh_06::WindowHandle,
) -> Result<NativeWidget, Error> {
use rwh_06::RawWindowHandle::AndroidNdk;

Expand All @@ -155,6 +185,32 @@ impl Connection {
_ => Err(Error::IncompatibleNativeWidget),
}
}

#[cfg(all(feature = "sm-raw-window-handle-06", ohos_platform))]
#[inline]
fn create_native_widget_from_rwh_06_handle(
handle: rwh_06::WindowHandle,
) -> Result<NativeWidget, Error> {
use rwh_06::RawWindowHandle::OhosNdk;

match handle.as_raw() {
OhosNdk(handle) => Ok(NativeWidget {
native_window: handle.native_window.as_ptr().cast(),
}),
_ => Err(Error::IncompatibleNativeWidget),
}
}

/// Create a native widget type from the given `WindowHandle`.
#[cfg(feature = "sm-raw-window-handle-06")]
#[inline]
pub fn create_native_widget_from_window_handle(
&self,
handle: rwh_06::WindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
Self::create_native_widget_from_rwh_06_handle(handle)
}
}

impl NativeConnection {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// surfman/surfman/src/platform/android/context.rs
// surfman/surfman/src/platform/egl/context.rs
//
//! OpenGL rendering contexts.

Expand Down Expand Up @@ -212,11 +212,12 @@ impl Device {
..
}) => (egl_surface, egl_surface),
Framebuffer::External(ExternalEGLSurfaces { draw, read }) => (draw, read),
#[cfg(android_platform)]
Framebuffer::Surface(Surface {
objects: SurfaceObjects::HardwareBuffer { .. },
..
})
| Framebuffer::None => (context.pbuffer, context.pbuffer),
}) => (context.pbuffer, context.pbuffer),
Framebuffer::None => (context.pbuffer, context.pbuffer),
};

EGL_FUNCTIONS.with(|egl| {
Expand Down Expand Up @@ -366,11 +367,12 @@ impl Device {
..
}) => (egl_surface, egl_surface),
Framebuffer::External(ExternalEGLSurfaces { draw, read }) => (draw, read),
#[cfg(android_platform)]
Framebuffer::Surface(Surface {
objects: SurfaceObjects::HardwareBuffer { .. },
..
})
| Framebuffer::None => (context.pbuffer, context.pbuffer),
}) => (context.pbuffer, context.pbuffer),
Framebuffer::None => (context.pbuffer, context.pbuffer),
};

NativeContext {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// surfman/surfman/src/platform/android/device.rs
// surfman/surfman/src/platform/egl/device.rs
//
//! A thread-local handle to the device.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// surfman/surfman/src/platform/android/mod.rs
// surfman/surfman/src/platform/egl/mod.rs
//
//! Bindings to EGL on Android.

Expand All @@ -7,7 +7,11 @@ pub mod context;
pub mod device;
pub mod surface;

mod ffi;
#[cfg(android_platform)]
mod android_ffi;

#[cfg(ohos_platform)]
mod ohos_ffi;

#[path = "../../implementation/mod.rs"]
mod implementation;
Expand Down
46 changes: 46 additions & 0 deletions surfman/src/platform/egl/ohos_ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(unused)]

#[repr(C)]
pub struct NativeWindow {
_unused: [u8; 0],
}

pub type OHNativeWindow = NativeWindow;

#[repr(transparent)]
pub(crate) struct NativeWindowOperation(core::ffi::c_int);

impl NativeWindowOperation {
pub const GET_BUFFER_GEOMETRY: Self = Self(1);
}

/// According to the [native window guidelines], users need to link against
/// both the NDK and `native_window`.
/// [native window guidelines]: <https://gitee.com/openharmony/docs/blob/master/en/application-dev/graphics/native-window-guidelines.md>
#[link(name = "native_window")]
#[link(name = "ace_ndk.z")]
extern "C" {
/// Sets or obtains the attributes of a native window
///
/// Can be used to query information like height and width.
/// See the official [Documentation] for detailed usage information.
///
/// # Safety
///
/// The `window` handle must be valid.
/// The variable arguments which must be passed to this function vary depending on the
/// value of `code`.
/// For `NativeWindowOperation::GET_BUFFER_GEOMETRY` the function two output i32 pointers
/// `height: *mut i32` and `width: *mut i32` must be passed as variadic arguments.
///
///
/// [Documentation]: <https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis-arkgraphics2d/_native_window.md>
pub(crate) fn OH_NativeWindow_NativeWindowHandleOpt(
window: *mut OHNativeWindow,
code: NativeWindowOperation,
...
) -> i32;
}
Loading