Make HeapFloat32Array generic (#31167)

* Make HeapFloat32Array generic

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Define all the methods defaults on the HeapTypedArray trait

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Use generic type instead of trait

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

---------

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi 2024-01-29 12:57:50 +01:00 committed by GitHub
parent 7d1b19c865
commit 742d3ed97f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 78 additions and 56 deletions

View file

@ -6,9 +6,10 @@ use std::cmp::min;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::{CustomAutoRooterGuard, HandleObject}; use js::rust::{CustomAutoRooterGuard, HandleObject};
use js::typedarray::Float32Array; use js::typedarray::{Float32, Float32Array};
use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer; use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer;
use super::bindings::typedarrays::HeapTypedArray;
use crate::dom::audionode::MAX_CHANNEL_COUNT; use crate::dom::audionode::MAX_CHANNEL_COUNT;
use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{ use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{
@ -18,7 +19,6 @@ use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::typedarrays::HeapFloat32Array;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::realms::enter_realm; use crate::realms::enter_realm;
@ -42,7 +42,7 @@ pub struct AudioBuffer {
reflector_: Reflector, reflector_: Reflector,
/// Float32Arrays returned by calls to GetChannelData. /// Float32Arrays returned by calls to GetChannelData.
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
js_channels: DomRefCell<Vec<HeapFloat32Array>>, js_channels: DomRefCell<Vec<HeapTypedArray<Float32>>>,
/// Aggregates the data from js_channels. /// Aggregates the data from js_channels.
/// This is Some<T> iff the buffers in js_channels are detached. /// This is Some<T> iff the buffers in js_channels are detached.
#[ignore_malloc_size_of = "servo_media"] #[ignore_malloc_size_of = "servo_media"]
@ -63,7 +63,7 @@ impl AudioBuffer {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn new_inherited(number_of_channels: u32, length: u32, sample_rate: f32) -> AudioBuffer { pub fn new_inherited(number_of_channels: u32, length: u32, sample_rate: f32) -> AudioBuffer {
let vec = (0..number_of_channels) let vec = (0..number_of_channels)
.map(|_| HeapFloat32Array::default()) .map(|_| HeapTypedArray::default())
.collect(); .collect();
AudioBuffer { AudioBuffer {
reflector_: Reflector::new(), reflector_: Reflector::new(),

View file

@ -4,35 +4,53 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use std::marker::PhantomData;
use std::ptr; use std::ptr;
use js::jsapi::{Heap, JSObject, JS_GetArrayBufferViewBuffer}; use js::jsapi::{Heap, JSObject, JS_GetArrayBufferViewBuffer};
use js::rust::wrappers::DetachArrayBuffer; use js::rust::wrappers::DetachArrayBuffer;
use js::rust::{CustomAutoRooterGuard, MutableHandleObject}; use js::rust::{CustomAutoRooterGuard, MutableHandleObject};
use js::typedarray::{ use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElementCreator};
CreateWith, Float32Array, JSObjectStorage, TypedArray, TypedArrayElement,
TypedArrayElementCreator,
};
use crate::script_runtime::JSContext; use crate::script_runtime::JSContext;
#[derive(Default, JSTraceable)] pub struct HeapTypedArray<T> {
pub struct HeapFloat32Array {
internal: Box<Heap<*mut JSObject>>, internal: Box<Heap<*mut JSObject>>,
phantom: PhantomData<T>,
} }
impl HeapFloat32Array { unsafe impl<T> crate::dom::bindings::trace::JSTraceable for HeapTypedArray<T> {
pub fn set_data(&self, cx: JSContext, data: &[f32]) -> Result<(), ()> { #[inline]
unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) {
self.internal.trace(tracer);
}
}
impl<T> HeapTypedArray<T>
where
T: TypedArrayElement + TypedArrayElementCreator,
T::Element: Clone + Copy,
{
pub fn default() -> HeapTypedArray<T> {
HeapTypedArray {
internal: Box::new(Heap::default()),
phantom: PhantomData::default(),
}
}
pub fn set_data(&self, cx: JSContext, data: &[T::Element]) -> Result<(), ()> {
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
let _: Float32Array = create_typed_array(cx, data, array.handle_mut())?; let _: TypedArray<T, *mut JSObject> = create_typed_array(cx, data, array.handle_mut())?;
self.internal.set(*array); self.internal.set(*array);
Ok(()) Ok(())
} }
pub fn acquire_data(&self, cx: JSContext) -> Result<Vec<f32>, ()> { pub fn acquire_data(&self, cx: JSContext) -> Result<Vec<T::Element>, ()> {
assert!(self.is_initialized()); assert!(self.is_initialized());
typedarray!(in(*cx) let array: Float32Array = self.internal.get()); typedarray!(in(*cx) let array: TypedArray = self.internal.get());
let data = if let Ok(array) = array { let data = if let Ok(array) =
array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()>
{
let data = array.to_vec(); let data = array.to_vec();
let mut is_shared = false; let mut is_shared = false;
unsafe { unsafe {
@ -53,13 +71,15 @@ impl HeapFloat32Array {
pub fn copy_data_to( pub fn copy_data_to(
&self, &self,
cx: JSContext, cx: JSContext,
dest: &mut [f32], dest: &mut [T::Element],
source_start: usize, source_start: usize,
length: usize, length: usize,
) -> Result<(), ()> { ) -> Result<(), ()> {
assert!(self.is_initialized()); assert!(self.is_initialized());
typedarray!(in(*cx) let array: Float32Array = self.internal.get()); typedarray!(in(*cx) let array: TypedArray = self.internal.get());
let Ok(array) = array else { return Err(()) }; let Ok(array) = array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()> else{
return Err(())
};
unsafe { unsafe {
let slice = (*array).as_slice(); let slice = (*array).as_slice();
dest.copy_from_slice(&slice[source_start..length]); dest.copy_from_slice(&slice[source_start..length]);
@ -70,13 +90,16 @@ impl HeapFloat32Array {
pub fn copy_data_from( pub fn copy_data_from(
&self, &self,
cx: JSContext, cx: JSContext,
source: CustomAutoRooterGuard<Float32Array>, source: CustomAutoRooterGuard<TypedArray<T, *mut JSObject>>,
dest_start: usize, dest_start: usize,
length: usize, length: usize,
) -> Result<(), ()> { ) -> Result<(), ()> {
assert!(self.is_initialized()); assert!(self.is_initialized());
typedarray!(in(*cx) let mut array: Float32Array = self.internal.get()); typedarray!(in(*cx) let mut array: TypedArray = self.internal.get());
let Ok(mut array) = array else { return Err(()) }; let Ok(mut array) = array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()> else
{
return Err(())
};
unsafe { unsafe {
let slice = (*array).as_mut_slice(); let slice = (*array).as_mut_slice();
let (_, dest) = slice.split_at_mut(dest_start); let (_, dest) = slice.split_at_mut(dest_start);
@ -89,11 +112,11 @@ impl HeapFloat32Array {
!self.internal.get().is_null() !self.internal.get().is_null()
} }
pub fn get_internal(&self) -> Result<Float32Array, ()> { pub fn get_internal(&self) -> Result<TypedArray<T, *mut JSObject>, ()> {
Float32Array::from(self.internal.get()) TypedArray::from(self.internal.get())
} }
pub fn internal_to_option(&self) -> Option<Float32Array> { pub fn internal_to_option(&self) -> Option<TypedArray<T, *mut JSObject>> {
if self.is_initialized() { if self.is_initialized() {
Some(self.get_internal().expect("Failed to get internal.")) Some(self.get_internal().expect("Failed to get internal."))
} else { } else {
@ -103,16 +126,15 @@ impl HeapFloat32Array {
} }
} }
pub fn create_typed_array<T, S>( pub fn create_typed_array<T>(
cx: JSContext, cx: JSContext,
data: &[T::Element], data: &[T::Element],
dest: MutableHandleObject, dest: MutableHandleObject,
) -> Result<TypedArray<T, S>, ()> ) -> Result<TypedArray<T, *mut JSObject>, ()>
where where
T: TypedArrayElementCreator + TypedArrayElement, T: TypedArrayElement + TypedArrayElementCreator,
S: JSObjectStorage,
{ {
let res = unsafe { TypedArray::<T, S>::create(*cx, CreateWith::Slice(data), dest) }; let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Slice(data), dest) };
if res.is_err() { if res.is_err() {
Err(()) Err(())

View file

@ -3,9 +3,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::typedarray::Float32Array; use js::typedarray::{Float32, Float32Array};
use super::bindings::typedarrays::HeapFloat32Array; use super::bindings::typedarrays::HeapTypedArray;
use crate::dom::bindings::codegen::Bindings::GamepadPoseBinding::GamepadPoseMethods; use crate::dom::bindings::codegen::Bindings::GamepadPoseBinding::GamepadPoseMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
@ -16,17 +16,17 @@ use crate::script_runtime::JSContext;
pub struct GamepadPose { pub struct GamepadPose {
reflector_: Reflector, reflector_: Reflector,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
position: HeapFloat32Array, position: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
orientation: HeapFloat32Array, orientation: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
linear_vel: HeapFloat32Array, linear_vel: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
angular_vel: HeapFloat32Array, angular_vel: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
linear_acc: HeapFloat32Array, linear_acc: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
angular_acc: HeapFloat32Array, angular_acc: HeapTypedArray<Float32>,
} }
// TODO: support gamepad discovery // TODO: support gamepad discovery
@ -35,12 +35,12 @@ impl GamepadPose {
fn new_inherited() -> GamepadPose { fn new_inherited() -> GamepadPose {
GamepadPose { GamepadPose {
reflector_: Reflector::new(), reflector_: Reflector::new(),
position: HeapFloat32Array::default(), position: HeapTypedArray::default(),
orientation: HeapFloat32Array::default(), orientation: HeapTypedArray::default(),
linear_vel: HeapFloat32Array::default(), linear_vel: HeapTypedArray::default(),
angular_vel: HeapFloat32Array::default(), angular_vel: HeapTypedArray::default(),
linear_acc: HeapFloat32Array::default(), linear_acc: HeapTypedArray::default(),
angular_acc: HeapFloat32Array::default(), angular_acc: HeapTypedArray::default(),
} }
} }

View file

@ -5,15 +5,15 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::{Angle, RigidTransform3D, Rotation3D, Vector3D}; use euclid::{Angle, RigidTransform3D, Rotation3D, Vector3D};
use js::rust::HandleObject; use js::rust::HandleObject;
use js::typedarray::Float32Array; use js::typedarray::{Float32, Float32Array};
use webxr_api::{ApiSpace, Ray}; use webxr_api::{ApiSpace, Ray};
use super::bindings::typedarrays::HeapTypedArray;
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit; use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::Bindings::XRRayBinding::{XRRayDirectionInit, XRRayMethods}; use crate::dom::bindings::codegen::Bindings::XRRayBinding::{XRRayDirectionInit, XRRayMethods};
use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::typedarrays::HeapFloat32Array;
use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::dompointreadonly::DOMPointReadOnly;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window; use crate::dom::window::Window;
@ -27,7 +27,7 @@ pub struct XRRay {
#[no_trace] #[no_trace]
ray: Ray<ApiSpace>, ray: Ray<ApiSpace>,
#[ignore_malloc_size_of = "defined in mozjs"] #[ignore_malloc_size_of = "defined in mozjs"]
matrix: HeapFloat32Array, matrix: HeapTypedArray<Float32>,
} }
impl XRRay { impl XRRay {
@ -35,7 +35,7 @@ impl XRRay {
XRRay { XRRay {
reflector_: Reflector::new(), reflector_: Reflector::new(),
ray, ray,
matrix: HeapFloat32Array::default(), matrix: HeapTypedArray::default(),
} }
} }

View file

@ -5,14 +5,14 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::{RigidTransform3D, Rotation3D, Vector3D}; use euclid::{RigidTransform3D, Rotation3D, Vector3D};
use js::rust::HandleObject; use js::rust::HandleObject;
use js::typedarray::Float32Array; use js::typedarray::{Float32, Float32Array};
use super::bindings::typedarrays::HeapTypedArray;
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit; use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods; use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods;
use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::typedarrays::HeapFloat32Array;
use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::dompointreadonly::DOMPointReadOnly;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window; use crate::dom::window::Window;
@ -29,7 +29,7 @@ pub struct XRRigidTransform {
transform: ApiRigidTransform, transform: ApiRigidTransform,
inverse: MutNullableDom<XRRigidTransform>, inverse: MutNullableDom<XRRigidTransform>,
#[ignore_malloc_size_of = "defined in mozjs"] #[ignore_malloc_size_of = "defined in mozjs"]
matrix: HeapFloat32Array, matrix: HeapTypedArray<Float32>,
} }
impl XRRigidTransform { impl XRRigidTransform {
@ -40,7 +40,7 @@ impl XRRigidTransform {
orientation: MutNullableDom::default(), orientation: MutNullableDom::default(),
transform, transform,
inverse: MutNullableDom::default(), inverse: MutNullableDom::default(),
matrix: HeapFloat32Array::default(), matrix: HeapTypedArray::default(),
} }
} }

View file

@ -4,13 +4,13 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::RigidTransform3D; use euclid::RigidTransform3D;
use js::typedarray::Float32Array; use js::typedarray::{Float32, Float32Array};
use webxr_api::{ApiSpace, View}; use webxr_api::{ApiSpace, View};
use super::bindings::typedarrays::HeapTypedArray;
use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::typedarrays::HeapFloat32Array;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrrigidtransform::XRRigidTransform;
use crate::dom::xrsession::{cast_transform, BaseSpace, BaseTransform, XRSession}; use crate::dom::xrsession::{cast_transform, BaseSpace, BaseTransform, XRSession};
@ -23,7 +23,7 @@ pub struct XRView {
eye: XREye, eye: XREye,
viewport_index: usize, viewport_index: usize,
#[ignore_malloc_size_of = "mozjs"] #[ignore_malloc_size_of = "mozjs"]
proj: HeapFloat32Array, proj: HeapTypedArray<Float32>,
#[ignore_malloc_size_of = "defined in rust-webxr"] #[ignore_malloc_size_of = "defined in rust-webxr"]
#[no_trace] #[no_trace]
view: View<ApiSpace>, view: View<ApiSpace>,
@ -43,7 +43,7 @@ impl XRView {
session: Dom::from_ref(session), session: Dom::from_ref(session),
eye, eye,
viewport_index, viewport_index,
proj: HeapFloat32Array::default(), proj: HeapTypedArray::default(),
view, view,
transform: Dom::from_ref(transform), transform: Dom::from_ref(transform),
} }