forked from mirrors/gecko-dev
		
	Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix https://bugzilla.mozilla.org/show_bug.cgi?id=1409255 <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because testing is on the Gecko side. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 4c538b642e4bdfbf42c522c5a59c258a6d14546e --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f9a6feed1088d0b0be2b55d7f0c2ec9c594ac33b
		
			
				
	
	
		
			209 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
use dom::bindings::codegen::Bindings::GamepadBinding;
 | 
						|
use dom::bindings::codegen::Bindings::GamepadBinding::GamepadMethods;
 | 
						|
use dom::bindings::inheritance::Castable;
 | 
						|
use dom::bindings::nonnull::NonNullJSObjectPtr;
 | 
						|
use dom::bindings::num::Finite;
 | 
						|
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
 | 
						|
use dom::bindings::root::{Dom, DomRoot};
 | 
						|
use dom::bindings::str::DOMString;
 | 
						|
use dom::event::Event;
 | 
						|
use dom::eventtarget::EventTarget;
 | 
						|
use dom::gamepadbuttonlist::GamepadButtonList;
 | 
						|
use dom::gamepadevent::{GamepadEvent, GamepadEventType};
 | 
						|
use dom::globalscope::GlobalScope;
 | 
						|
use dom::vrpose::VRPose;
 | 
						|
use dom_struct::dom_struct;
 | 
						|
use js::jsapi::{Heap, JSContext, JSObject};
 | 
						|
use js::typedarray::{Float64Array, CreateWith};
 | 
						|
use std::cell::Cell;
 | 
						|
use std::ptr;
 | 
						|
use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState};
 | 
						|
 | 
						|
#[dom_struct]
 | 
						|
pub struct Gamepad {
 | 
						|
    reflector_: Reflector,
 | 
						|
    gamepad_id: u32,
 | 
						|
    id: String,
 | 
						|
    index: Cell<i32>,
 | 
						|
    connected: Cell<bool>,
 | 
						|
    timestamp: Cell<f64>,
 | 
						|
    mapping_type: String,
 | 
						|
    axes: Heap<*mut JSObject>,
 | 
						|
    buttons: Dom<GamepadButtonList>,
 | 
						|
    pose: Option<Dom<VRPose>>,
 | 
						|
    #[ignore_malloc_size_of = "Defined in rust-webvr"]
 | 
						|
    hand: WebVRGamepadHand,
 | 
						|
    display_id: u32
 | 
						|
}
 | 
						|
 | 
						|
impl Gamepad {
 | 
						|
    fn new_inherited(gamepad_id: u32,
 | 
						|
                     id: String,
 | 
						|
                     index: i32,
 | 
						|
                     connected: bool,
 | 
						|
                     timestamp: f64,
 | 
						|
                     mapping_type: String,
 | 
						|
                     buttons: &GamepadButtonList,
 | 
						|
                     pose: Option<&VRPose>,
 | 
						|
                     hand: WebVRGamepadHand,
 | 
						|
                     display_id: u32) -> Gamepad {
 | 
						|
        Self {
 | 
						|
            reflector_: Reflector::new(),
 | 
						|
            gamepad_id: gamepad_id,
 | 
						|
            id: id,
 | 
						|
            index: Cell::new(index),
 | 
						|
            connected: Cell::new(connected),
 | 
						|
            timestamp: Cell::new(timestamp),
 | 
						|
            mapping_type: mapping_type,
 | 
						|
            axes: Heap::default(),
 | 
						|
            buttons: Dom::from_ref(buttons),
 | 
						|
            pose: pose.map(Dom::from_ref),
 | 
						|
            hand: hand,
 | 
						|
            display_id: display_id
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    #[allow(unsafe_code)]
 | 
						|
    pub fn new_from_vr(global: &GlobalScope,
 | 
						|
                       index: i32,
 | 
						|
                       data: &WebVRGamepadData,
 | 
						|
                       state: &WebVRGamepadState) -> DomRoot<Gamepad> {
 | 
						|
        let buttons = GamepadButtonList::new_from_vr(&global, &state.buttons);
 | 
						|
        let pose = VRPose::new(&global, &state.pose);
 | 
						|
 | 
						|
        let gamepad = reflect_dom_object(
 | 
						|
            Box::new(Gamepad::new_inherited(
 | 
						|
                state.gamepad_id,
 | 
						|
                data.name.clone(),
 | 
						|
                index,
 | 
						|
                state.connected,
 | 
						|
                state.timestamp,
 | 
						|
                "".into(),
 | 
						|
                &buttons,
 | 
						|
                Some(&pose),
 | 
						|
                data.hand.clone(),
 | 
						|
                data.display_id
 | 
						|
            )),
 | 
						|
            global,
 | 
						|
            GamepadBinding::Wrap
 | 
						|
        );
 | 
						|
 | 
						|
        let cx = global.get_cx();
 | 
						|
        rooted!(in (cx) let mut array = ptr::null_mut());
 | 
						|
        unsafe {
 | 
						|
            let _ = Float64Array::create(cx, CreateWith::Slice(&state.axes), array.handle_mut());
 | 
						|
        }
 | 
						|
        gamepad.axes.set(array.get());
 | 
						|
 | 
						|
        gamepad
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
impl GamepadMethods for Gamepad {
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-id
 | 
						|
    fn Id(&self) -> DOMString {
 | 
						|
        DOMString::from(self.id.clone())
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-index
 | 
						|
    fn Index(&self) -> i32 {
 | 
						|
        self.index.get()
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-connected
 | 
						|
    fn Connected(&self) -> bool {
 | 
						|
        self.connected.get()
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-timestamp
 | 
						|
    fn Timestamp(&self) -> Finite<f64> {
 | 
						|
        Finite::wrap(self.timestamp.get())
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-mapping
 | 
						|
    fn Mapping(&self) -> DOMString {
 | 
						|
        DOMString::from(self.mapping_type.clone())
 | 
						|
    }
 | 
						|
 | 
						|
    #[allow(unsafe_code)]
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-axes
 | 
						|
    unsafe fn Axes(&self, _cx: *mut JSContext) -> NonNullJSObjectPtr {
 | 
						|
        NonNullJSObjectPtr::new_unchecked(self.axes.get())
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/#dom-gamepad-buttons
 | 
						|
    fn Buttons(&self) -> DomRoot<GamepadButtonList> {
 | 
						|
        DomRoot::from_ref(&*self.buttons)
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/extensions.html#gamepadhand-enum
 | 
						|
    fn Hand(&self) -> DOMString {
 | 
						|
        let value = match self.hand {
 | 
						|
            WebVRGamepadHand::Unknown => "",
 | 
						|
            WebVRGamepadHand::Left => "left",
 | 
						|
            WebVRGamepadHand::Right => "right"
 | 
						|
        };
 | 
						|
        value.into()
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/gamepad/extensions.html#dom-gamepad-pose
 | 
						|
    fn GetPose(&self) -> Option<DomRoot<VRPose>> {
 | 
						|
        self.pose.as_ref().map(|p| DomRoot::from_ref(&**p))
 | 
						|
    }
 | 
						|
 | 
						|
    // https://w3c.github.io/webvr/spec/1.1/#gamepad-getvrdisplays-attribute
 | 
						|
    fn DisplayId(&self) -> u32 {
 | 
						|
        self.display_id
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
impl Gamepad {
 | 
						|
    #[allow(unsafe_code)]
 | 
						|
    pub fn update_from_vr(&self, state: &WebVRGamepadState) {
 | 
						|
        self.timestamp.set(state.timestamp);
 | 
						|
        unsafe {
 | 
						|
            let cx = self.global().get_cx();
 | 
						|
            typedarray!(in(cx) let axes: Float64Array = self.axes.get());
 | 
						|
            if let Ok(mut array) = axes {
 | 
						|
                array.update(&state.axes);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        self.buttons.sync_from_vr(&state.buttons);
 | 
						|
        if let Some(ref pose) = self.pose {
 | 
						|
            pose.update(&state.pose);
 | 
						|
        }
 | 
						|
        self.update_connected(state.connected);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn gamepad_id(&self) -> u32 {
 | 
						|
        self.gamepad_id
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn update_connected(&self, connected: bool) {
 | 
						|
        if self.connected.get() == connected {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        self.connected.set(connected);
 | 
						|
 | 
						|
        let event_type = if connected {
 | 
						|
            GamepadEventType::Connected
 | 
						|
        } else {
 | 
						|
            GamepadEventType::Disconnected
 | 
						|
        };
 | 
						|
 | 
						|
        self.notify_event(event_type);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn update_index(&self, index: i32) {
 | 
						|
        self.index.set(index);
 | 
						|
    }
 | 
						|
 | 
						|
    pub fn notify_event(&self, event_type: GamepadEventType) {
 | 
						|
        let event = GamepadEvent::new_with_type(&self.global(), event_type, &self);
 | 
						|
        event.upcast::<Event>().fire(self.global().as_window().upcast::<EventTarget>());
 | 
						|
    }
 | 
						|
}
 |