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 js::rust::{CustomAutoRooterGuard, HandleObject};
use js::typedarray::Float32Array;
use js::typedarray::{Float32, Float32Array};
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::bindings::cell::{DomRefCell, Ref};
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::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::typedarrays::HeapFloat32Array;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use crate::realms::enter_realm;
@ -42,7 +42,7 @@ pub struct AudioBuffer {
reflector_: Reflector,
/// Float32Arrays returned by calls to GetChannelData.
#[ignore_malloc_size_of = "mozjs"]
js_channels: DomRefCell<Vec<HeapFloat32Array>>,
js_channels: DomRefCell<Vec<HeapTypedArray<Float32>>>,
/// Aggregates the data from js_channels.
/// This is Some<T> iff the buffers in js_channels are detached.
#[ignore_malloc_size_of = "servo_media"]
@ -63,7 +63,7 @@ impl AudioBuffer {
#[allow(unsafe_code)]
pub fn new_inherited(number_of_channels: u32, length: u32, sample_rate: f32) -> AudioBuffer {
let vec = (0..number_of_channels)
.map(|_| HeapFloat32Array::default())
.map(|_| HeapTypedArray::default())
.collect();
AudioBuffer {
reflector_: Reflector::new(),

View file

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

View file

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

View file

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

View file

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

View file

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