From cccbc46d0ceb22c4afc0c58de6b599049dc72154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 06:08:14 -0500 Subject: [PATCH 001/166] servo: Merge #18019 - stylo: Devirtualize nsIAtom refcounting (from emilio:devirt-nsiatom); r=froydnj Bug: 1362338 Reviewed-by: froydnj MozReview-Commit-ID: 3q5rz3L8quQ Source-Repo: https://github.com/servo/servo Source-Revision: 77cb5371b38153d9c81cd469a59ea20a3405ba80 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f54fd90aaa4d32353eb34b23e12ef10e997e7047 --- .../style/gecko/generated/atom_macro.rs | 24 - .../style/gecko/generated/structs_debug.rs | 1398 +++++++++-------- .../style/gecko/generated/structs_release.rs | 1380 ++++++++-------- .../style/gecko_string_cache/mod.rs | 4 +- 4 files changed, 1522 insertions(+), 1284 deletions(-) diff --git a/servo/components/style/gecko/generated/atom_macro.rs b/servo/components/style/gecko/generated/atom_macro.rs index 8c330f92b49d..00114fe62461 100644 --- a/servo/components/style/gecko/generated/atom_macro.rs +++ b/servo/components/style/gecko/generated/atom_macro.rs @@ -1812,16 +1812,10 @@ cfg_if! { pub static nsGkAtoms_onmozpointerlockchange: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms21onmozpointerlockerrorE"] pub static nsGkAtoms_onmozpointerlockerror: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms15onmoztimechangeE"] - pub static nsGkAtoms_onmoztimechange: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms21onMozMousePixelScrollE"] pub static nsGkAtoms_onMozMousePixelScroll: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms24onMozScrolledAreaChangedE"] pub static nsGkAtoms_onMozScrolledAreaChanged: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms18onmoznetworkuploadE"] - pub static nsGkAtoms_onmoznetworkupload: *mut nsIAtom; - #[link_name = "_ZN9nsGkAtoms20onmoznetworkdownloadE"] - pub static nsGkAtoms_onmoznetworkdownload: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms21onmapfolderlistingreqE"] pub static nsGkAtoms_onmapfolderlistingreq: *mut nsIAtom; #[link_name = "_ZN9nsGkAtoms23onmapmessageslistingreqE"] @@ -6943,16 +6937,10 @@ cfg_if! { pub static nsGkAtoms_onmozpointerlockchange: *mut nsIAtom; #[link_name = "?onmozpointerlockerror@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onmozpointerlockerror: *mut nsIAtom; - #[link_name = "?onmoztimechange@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmoztimechange: *mut nsIAtom; #[link_name = "?onMozMousePixelScroll@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onMozMousePixelScroll: *mut nsIAtom; #[link_name = "?onMozScrolledAreaChanged@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onMozScrolledAreaChanged: *mut nsIAtom; - #[link_name = "?onmoznetworkupload@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmoznetworkupload: *mut nsIAtom; - #[link_name = "?onmoznetworkdownload@nsGkAtoms@@2PEAVnsIAtom@@EA"] - pub static nsGkAtoms_onmoznetworkdownload: *mut nsIAtom; #[link_name = "?onmapfolderlistingreq@nsGkAtoms@@2PEAVnsIAtom@@EA"] pub static nsGkAtoms_onmapfolderlistingreq: *mut nsIAtom; #[link_name = "?onmapmessageslistingreq@nsGkAtoms@@2PEAVnsIAtom@@EA"] @@ -12074,16 +12062,10 @@ cfg_if! { pub static nsGkAtoms_onmozpointerlockchange: *mut nsIAtom; #[link_name = "\x01?onmozpointerlockerror@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onmozpointerlockerror: *mut nsIAtom; - #[link_name = "\x01?onmoztimechange@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmoztimechange: *mut nsIAtom; #[link_name = "\x01?onMozMousePixelScroll@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onMozMousePixelScroll: *mut nsIAtom; #[link_name = "\x01?onMozScrolledAreaChanged@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onMozScrolledAreaChanged: *mut nsIAtom; - #[link_name = "\x01?onmoznetworkupload@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmoznetworkupload: *mut nsIAtom; - #[link_name = "\x01?onmoznetworkdownload@nsGkAtoms@@2PAVnsIAtom@@A"] - pub static nsGkAtoms_onmoznetworkdownload: *mut nsIAtom; #[link_name = "\x01?onmapfolderlistingreq@nsGkAtoms@@2PAVnsIAtom@@A"] pub static nsGkAtoms_onmapfolderlistingreq: *mut nsIAtom; #[link_name = "\x01?onmapmessageslistingreq@nsGkAtoms@@2PAVnsIAtom@@A"] @@ -17208,16 +17190,10 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozpointerlockchange as *mut _) } }; ("onmozpointerlockerror") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmozpointerlockerror as *mut _) } }; -("onmoztimechange") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmoztimechange as *mut _) } }; ("onMozMousePixelScroll") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onMozMousePixelScroll as *mut _) } }; ("onMozScrolledAreaChanged") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onMozScrolledAreaChanged as *mut _) } }; -("onmoznetworkupload") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmoznetworkupload as *mut _) } }; -("onmoznetworkdownload") => - { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmoznetworkdownload as *mut _) } }; ("onmapfolderlistingreq") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_onmapfolderlistingreq as *mut _) } }; ("onmapmessageslistingreq") => diff --git a/servo/components/style/gecko/generated/structs_debug.rs b/servo/components/style/gecko/generated/structs_debug.rs index 33189e383700..ce891a52f818 100644 --- a/servo/components/style/gecko/generated/structs_debug.rs +++ b/servo/components/style/gecko/generated/structs_debug.rs @@ -1052,7 +1052,8 @@ pub mod root { } pub type pair_first_type<_T1> = _T1; pub type pair_second_type<_T2> = _T2; - pub type conditional_type<_If> = _If; + pub type pair__PCCP = u8; + pub type pair__PCCFP = u8; #[repr(C)] #[derive(Debug, Copy)] pub struct input_iterator_tag { @@ -1072,113 +1073,32 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] - #[derive(Debug, Copy)] - pub struct forward_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_forward_iterator_tag() { - assert_eq!(::std::mem::size_of::() , 1usize - , concat ! ( - "Size of: " , stringify ! ( forward_iterator_tag ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( forward_iterator_tag ) - )); - } - impl Clone for forward_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct bidirectional_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_bidirectional_iterator_tag() { - assert_eq!(::std::mem::size_of::() , - 1usize , concat ! ( - "Size of: " , stringify ! ( bidirectional_iterator_tag - ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( - bidirectional_iterator_tag ) )); - } - impl Clone for bidirectional_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct random_access_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_random_access_iterator_tag() { - assert_eq!(::std::mem::size_of::() , - 1usize , concat ! ( - "Size of: " , stringify ! ( random_access_iterator_tag - ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( - random_access_iterator_tag ) )); - } - impl Clone for random_access_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct iterator { pub _address: u8, } + pub type iterator_iterator_category<_Category> = _Category; pub type iterator_value_type<_Tp> = _Tp; pub type iterator_difference_type<_Distance> = _Distance; pub type iterator_pointer<_Pointer> = _Pointer; pub type iterator_reference<_Reference> = _Reference; - pub type iterator_iterator_category<_Category> = _Category; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct atomic { } - pub type atomic___base = u8; - pub type __bit_iterator_difference_type = [u8; 0usize]; - pub type __bit_iterator_value_type = bool; - pub type __bit_iterator_pointer = u8; - pub type __bit_iterator_reference = u8; - pub type __bit_iterator_iterator_category = - root::std::random_access_iterator_tag; - pub type __bit_iterator___storage_type = [u8; 0usize]; - pub type __bit_iterator___storage_pointer = [u8; 0usize]; + pub type _Base_bitset__WordT = ::std::os::raw::c_ulong; + pub type bitset__Base = u8; + pub type bitset__WordT = ::std::os::raw::c_ulong; #[repr(C)] - pub struct __bit_const_reference { - pub __seg_: root::std::__bit_const_reference___storage_pointer, - pub __mask_: root::std::__bit_const_reference___storage_type, + #[derive(Debug)] + pub struct bitset_reference { + pub _M_wp: *mut root::std::bitset__WordT, + pub _M_bpos: usize, } - pub type __bit_const_reference___storage_type = [u8; 0usize]; - pub type __bit_const_reference___storage_pointer = [u8; 0usize]; - pub type __bit_reference___storage_type = [u8; 0usize]; - pub type __bit_reference___storage_pointer = [u8; 0usize]; - pub type __bitset_difference_type = isize; - pub type __bitset_size_type = usize; - pub type __bitset___storage_type = root::std::__bitset_size_type; - pub type __bitset___self = u8; - pub type __bitset___storage_pointer = - *mut root::std::__bitset___storage_type; - pub type __bitset___const_storage_pointer = - *const root::std::__bitset___storage_type; - pub const __bitset___bits_per_word: ::std::os::raw::c_uint = 64; - pub type __bitset_reference = u8; - pub type __bitset_const_reference = root::std::__bit_const_reference; - pub type __bitset_iterator = u8; - pub type __bitset_const_iterator = u8; - extern "C" { - #[link_name = "__n_words"] - pub static bitset___n_words: ::std::os::raw::c_uint; - } - pub type bitset_base = u8; - pub type bitset_reference = root::std::bitset_base; - pub type bitset_const_reference = root::std::bitset_base; + } + pub mod __gnu_cxx { + #[allow(unused_imports)] + use self::super::super::root; } pub mod mozilla { #[allow(unused_imports)] @@ -1225,8 +1145,9 @@ pub mod root { root::nsSubstringTuple; pub type nsStringRepr_string_type = ::nsstring::nsStringRepr; pub type nsStringRepr_const_iterator = - root::nsReadingIterator; - pub type nsStringRepr_iterator = root::nsWritingIterator; + root::nsReadingIterator; + pub type nsStringRepr_iterator = + root::nsWritingIterator; pub type nsStringRepr_comparator_type = root::nsStringComparator; pub type nsStringRepr_char_iterator = *mut root::mozilla::detail::nsStringRepr_char_type; @@ -1293,9 +1214,9 @@ pub mod root { root::nsCSubstringTuple; pub type nsCStringRepr_string_type = root::nsCString; pub type nsCStringRepr_const_iterator = - root::nsReadingIterator<::std::os::raw::c_char>; + root::nsReadingIterator; pub type nsCStringRepr_iterator = - root::nsWritingIterator<::std::os::raw::c_char>; + root::nsWritingIterator; pub type nsCStringRepr_comparator_type = root::nsCStringComparator; pub type nsCStringRepr_char_iterator = @@ -2311,7 +2232,7 @@ pub mod root { } } #[repr(C)] - #[derive(Debug, Copy)] + #[derive(Debug)] pub struct ThreadSafeAutoRefCnt { pub mValue: u64, } @@ -2332,9 +2253,6 @@ pub mod root { ThreadSafeAutoRefCnt ) , "::" , stringify ! ( mValue ) )); } - impl Clone for ThreadSafeAutoRefCnt { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug)] pub struct OwningNonNull { @@ -5075,6 +4993,7 @@ pub mod root { pub _base: root::nsStyleContext, pub mPresContext: *mut root::nsPresContext, pub mSource: root::ServoComputedData, + pub mNextInheritingAnonBoxStyle: root::RefPtr, } #[test] fn bindgen_test_layout_ServoStyleContext() { @@ -5087,17 +5006,24 @@ pub mod root { )); assert_eq! (unsafe { & ( * ( 0 as * const ServoStyleContext ) ) . - mPresContext as * const _ as usize } , 32usize , + mPresContext as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleContext ) , "::" , stringify ! ( mPresContext ) )); assert_eq! (unsafe { & ( * ( 0 as * const ServoStyleContext ) ) . mSource - as * const _ as usize } , 40usize , concat ! ( + as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleContext ) , "::" , stringify ! ( mSource ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const ServoStyleContext ) ) . + mNextInheritingAnonBoxStyle as * const _ as usize } , + 256usize , concat ! ( + "Alignment of field: " , stringify ! ( + ServoStyleContext ) , "::" , stringify ! ( + mNextInheritingAnonBoxStyle ) )); } #[repr(C)] #[derive(Debug)] @@ -6311,6 +6237,7 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( Runnable ) )); } + pub type Preferences_PrefSetting = root::mozilla::dom::PrefSetting; #[repr(C)] #[derive(Debug)] pub struct CycleCollectedJSContext_RunInMetastableStateData { @@ -6371,91 +6298,93 @@ pub mod root { eUseCounter_SVGSVGElement_currentScale_setter = 2, eUseCounter_property_Fill = 3, eUseCounter_property_FillOpacity = 4, - eUseCounter_PushManager_subscribe = 5, - eUseCounter_PushSubscription_unsubscribe = 6, - eUseCounter_Window_sidebar_getter = 7, - eUseCounter_Window_sidebar_setter = 8, - eUseCounter_External_addSearchEngine = 9, - eUseCounter_OfflineResourceList_swapCache = 10, - eUseCounter_OfflineResourceList_update = 11, - eUseCounter_OfflineResourceList_status_getter = 12, - eUseCounter_OfflineResourceList_status_setter = 13, - eUseCounter_OfflineResourceList_onchecking_getter = 14, - eUseCounter_OfflineResourceList_onchecking_setter = 15, - eUseCounter_OfflineResourceList_onerror_getter = 16, - eUseCounter_OfflineResourceList_onerror_setter = 17, - eUseCounter_OfflineResourceList_onnoupdate_getter = 18, - eUseCounter_OfflineResourceList_onnoupdate_setter = 19, - eUseCounter_OfflineResourceList_ondownloading_getter = 20, - eUseCounter_OfflineResourceList_ondownloading_setter = 21, - eUseCounter_OfflineResourceList_onprogress_getter = 22, - eUseCounter_OfflineResourceList_onprogress_setter = 23, - eUseCounter_OfflineResourceList_onupdateready_getter = 24, - eUseCounter_OfflineResourceList_onupdateready_setter = 25, - eUseCounter_OfflineResourceList_oncached_getter = 26, - eUseCounter_OfflineResourceList_oncached_setter = 27, - eUseCounter_OfflineResourceList_onobsolete_getter = 28, - eUseCounter_OfflineResourceList_onobsolete_setter = 29, - eUseCounter_IDBDatabase_createMutableFile = 30, - eUseCounter_IDBDatabase_mozCreateFileHandle = 31, - eUseCounter_IDBMutableFile_open = 32, - eUseCounter_IDBMutableFile_getFile = 33, - eUseCounter_DataTransfer_addElement = 34, - eUseCounter_DataTransfer_mozItemCount_getter = 35, - eUseCounter_DataTransfer_mozItemCount_setter = 36, - eUseCounter_DataTransfer_mozCursor_getter = 37, - eUseCounter_DataTransfer_mozCursor_setter = 38, - eUseCounter_DataTransfer_mozTypesAt = 39, - eUseCounter_DataTransfer_mozClearDataAt = 40, - eUseCounter_DataTransfer_mozSetDataAt = 41, - eUseCounter_DataTransfer_mozGetDataAt = 42, - eUseCounter_DataTransfer_mozUserCancelled_getter = 43, - eUseCounter_DataTransfer_mozUserCancelled_setter = 44, - eUseCounter_DataTransfer_mozSourceNode_getter = 45, - eUseCounter_DataTransfer_mozSourceNode_setter = 46, - eUseCounter_GetAttributeNode = 47, - eUseCounter_SetAttributeNode = 48, - eUseCounter_GetAttributeNodeNS = 49, - eUseCounter_SetAttributeNodeNS = 50, - eUseCounter_RemoveAttributeNode = 51, - eUseCounter_CreateAttribute = 52, - eUseCounter_CreateAttributeNS = 53, - eUseCounter_NodeValue = 54, - eUseCounter_TextContent = 55, - eUseCounter_EnablePrivilege = 56, - eUseCounter_DOMExceptionCode = 57, - eUseCounter_NoExposedProps = 58, - eUseCounter_MutationEvent = 59, - eUseCounter_Components = 60, - eUseCounter_PrefixedVisibilityAPI = 61, - eUseCounter_NodeIteratorDetach = 62, - eUseCounter_LenientThis = 63, - eUseCounter_GetPreventDefault = 64, - eUseCounter_GetSetUserData = 65, - eUseCounter_MozGetAsFile = 66, - eUseCounter_UseOfCaptureEvents = 67, - eUseCounter_UseOfReleaseEvents = 68, - eUseCounter_UseOfDOM3LoadMethod = 69, - eUseCounter_ChromeUseOfDOM3LoadMethod = 70, - eUseCounter_ShowModalDialog = 71, - eUseCounter_Window_Content = 72, - eUseCounter_SyncXMLHttpRequest = 73, - eUseCounter_Window_Cc_ontrollers = 74, - eUseCounter_ImportXULIntoContent = 75, - eUseCounter_PannerNodeDoppler = 76, - eUseCounter_NavigatorGetUserMedia = 77, - eUseCounter_WebrtcDeprecatedPrefix = 78, - eUseCounter_RTCPeerConnectionGetStreams = 79, - eUseCounter_AppCache = 80, - eUseCounter_PrefixedImageSmoothingEnabled = 81, - eUseCounter_PrefixedFullscreenAPI = 82, - eUseCounter_LenientSetter = 83, - eUseCounter_FileLastModifiedDate = 84, - eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap = 85, - eUseCounter_URLCreateObjectURL_MediaStream = 86, - eUseCounter_XMLBaseAttribute = 87, - eUseCounter_XMLBaseAttributeForStyleAttr = 88, - eUseCounter_Count = 89, + eUseCounter_XMLDocument_async_getter = 5, + eUseCounter_XMLDocument_async_setter = 6, + eUseCounter_PushManager_subscribe = 7, + eUseCounter_PushSubscription_unsubscribe = 8, + eUseCounter_Window_sidebar_getter = 9, + eUseCounter_Window_sidebar_setter = 10, + eUseCounter_External_addSearchEngine = 11, + eUseCounter_OfflineResourceList_swapCache = 12, + eUseCounter_OfflineResourceList_update = 13, + eUseCounter_OfflineResourceList_status_getter = 14, + eUseCounter_OfflineResourceList_status_setter = 15, + eUseCounter_OfflineResourceList_onchecking_getter = 16, + eUseCounter_OfflineResourceList_onchecking_setter = 17, + eUseCounter_OfflineResourceList_onerror_getter = 18, + eUseCounter_OfflineResourceList_onerror_setter = 19, + eUseCounter_OfflineResourceList_onnoupdate_getter = 20, + eUseCounter_OfflineResourceList_onnoupdate_setter = 21, + eUseCounter_OfflineResourceList_ondownloading_getter = 22, + eUseCounter_OfflineResourceList_ondownloading_setter = 23, + eUseCounter_OfflineResourceList_onprogress_getter = 24, + eUseCounter_OfflineResourceList_onprogress_setter = 25, + eUseCounter_OfflineResourceList_onupdateready_getter = 26, + eUseCounter_OfflineResourceList_onupdateready_setter = 27, + eUseCounter_OfflineResourceList_oncached_getter = 28, + eUseCounter_OfflineResourceList_oncached_setter = 29, + eUseCounter_OfflineResourceList_onobsolete_getter = 30, + eUseCounter_OfflineResourceList_onobsolete_setter = 31, + eUseCounter_IDBDatabase_createMutableFile = 32, + eUseCounter_IDBDatabase_mozCreateFileHandle = 33, + eUseCounter_IDBMutableFile_open = 34, + eUseCounter_IDBMutableFile_getFile = 35, + eUseCounter_DataTransfer_addElement = 36, + eUseCounter_DataTransfer_mozItemCount_getter = 37, + eUseCounter_DataTransfer_mozItemCount_setter = 38, + eUseCounter_DataTransfer_mozCursor_getter = 39, + eUseCounter_DataTransfer_mozCursor_setter = 40, + eUseCounter_DataTransfer_mozTypesAt = 41, + eUseCounter_DataTransfer_mozClearDataAt = 42, + eUseCounter_DataTransfer_mozSetDataAt = 43, + eUseCounter_DataTransfer_mozGetDataAt = 44, + eUseCounter_DataTransfer_mozUserCancelled_getter = 45, + eUseCounter_DataTransfer_mozUserCancelled_setter = 46, + eUseCounter_DataTransfer_mozSourceNode_getter = 47, + eUseCounter_DataTransfer_mozSourceNode_setter = 48, + eUseCounter_GetAttributeNode = 49, + eUseCounter_SetAttributeNode = 50, + eUseCounter_GetAttributeNodeNS = 51, + eUseCounter_SetAttributeNodeNS = 52, + eUseCounter_RemoveAttributeNode = 53, + eUseCounter_CreateAttribute = 54, + eUseCounter_CreateAttributeNS = 55, + eUseCounter_NodeValue = 56, + eUseCounter_TextContent = 57, + eUseCounter_EnablePrivilege = 58, + eUseCounter_DOMExceptionCode = 59, + eUseCounter_NoExposedProps = 60, + eUseCounter_MutationEvent = 61, + eUseCounter_Components = 62, + eUseCounter_PrefixedVisibilityAPI = 63, + eUseCounter_NodeIteratorDetach = 64, + eUseCounter_LenientThis = 65, + eUseCounter_GetPreventDefault = 66, + eUseCounter_GetSetUserData = 67, + eUseCounter_MozGetAsFile = 68, + eUseCounter_UseOfCaptureEvents = 69, + eUseCounter_UseOfReleaseEvents = 70, + eUseCounter_UseOfDOM3LoadMethod = 71, + eUseCounter_ChromeUseOfDOM3LoadMethod = 72, + eUseCounter_ShowModalDialog = 73, + eUseCounter_Window_Content = 74, + eUseCounter_SyncXMLHttpRequest = 75, + eUseCounter_Window_Cc_ontrollers = 76, + eUseCounter_ImportXULIntoContent = 77, + eUseCounter_PannerNodeDoppler = 78, + eUseCounter_NavigatorGetUserMedia = 79, + eUseCounter_WebrtcDeprecatedPrefix = 80, + eUseCounter_RTCPeerConnectionGetStreams = 81, + eUseCounter_AppCache = 82, + eUseCounter_PrefixedImageSmoothingEnabled = 83, + eUseCounter_PrefixedFullscreenAPI = 84, + eUseCounter_LenientSetter = 85, + eUseCounter_FileLastModifiedDate = 86, + eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap = 87, + eUseCounter_URLCreateObjectURL_MediaStream = 88, + eUseCounter_XMLBaseAttribute = 89, + eUseCounter_XMLBaseAttributeForStyleAttr = 90, + eUseCounter_Count = 91, } #[repr(C)] #[derive(Debug)] @@ -8350,6 +8279,8 @@ pub mod root { PropertyStyleAnimationValuePair ) , "::" , stringify ! ( mValue ) )); } + pub type ComputedKeyframeValues = + root::nsTArray; #[test] fn __bindgen_test_layout_DefaultDelete_open0_RawServoStyleSet_close0_instantiation() { assert_eq!(::std::mem::size_of::() , @@ -9941,6 +9872,7 @@ pub mod root { NS_ERROR_TRACKING_URI = 2153578530, NS_ERROR_UNWANTED_URI = 2153578531, NS_ERROR_BLOCKED_URI = 2153578533, + NS_ERROR_HARMFUL_URI = 2153578534, NS_ERROR_SAVE_LINK_AS_TIMEOUT = 2153578528, NS_ERROR_PARSED_DATA_CACHED = 2153578529, NS_REFRESHURI_HEADER_FOUND = 6094850, @@ -11479,6 +11411,11 @@ pub mod root { AutoSetAsyncStackForNewCalls ) , "::" , stringify ! ( oldAsyncCallIsExplicit ) )); } + pub type WarningReporter = + ::std::option::Option; #[repr(C)] #[derive(Debug)] pub struct AutoHideScriptedCaller { @@ -11584,6 +11521,140 @@ pub mod root { pub struct JSCompartment { _unused: [u8; 0], } + /// Describes a single error or warning that occurs in the execution of script. + #[repr(C)] + #[derive(Debug)] + pub struct JSErrorReport { + pub _base: root::JSErrorBase, + pub linebuf_: *const u16, + pub linebufLength_: usize, + pub tokenOffset_: usize, + pub notes: root::mozilla::UniquePtr, + pub flags: ::std::os::raw::c_uint, + pub exnType: i16, + pub _bitfield_1: u8, + pub __bindgen_padding_0: u8, + } + #[test] + fn bindgen_test_layout_JSErrorReport() { + assert_eq!(::std::mem::size_of::() , 72usize , concat ! + ( "Size of: " , stringify ! ( JSErrorReport ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat + ! ( "Alignment of " , stringify ! ( JSErrorReport ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . linebuf_ as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( linebuf_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . linebufLength_ as + * const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( linebufLength_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . tokenOffset_ as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( tokenOffset_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . notes as * const + _ as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( notes ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . flags as * const + _ as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . exnType as * + const _ as usize } , 68usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( exnType ) )); + } + impl JSErrorReport { + #[inline] + pub fn isMuted(&self) -> bool { + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 1u64 as u8; + let val = (unit_field_val & mask) >> 0usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_isMuted(&mut self, val: bool) { + let mask = 1u64 as u8; + let val = val as u8 as u8; + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 0usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] + pub fn ownsLinebuf_(&self) -> bool { + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 2u64 as u8; + let val = (unit_field_val & mask) >> 1usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_ownsLinebuf_(&mut self, val: bool) { + let mask = 2u64 as u8; + let val = val as u8 as u8; + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 1usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] + pub fn new_bitfield_1(isMuted: bool, ownsLinebuf_: bool) -> u8 { + ({ ({ 0 } | ((isMuted as u8 as u8) << 0usize) & (1u64 as u8)) } | + ((ownsLinebuf_ as u8 as u8) << 1usize) & (2u64 as u8)) + } + } #[repr(C)] #[derive(Debug)] pub struct nsCOMPtr { @@ -12326,7 +12397,7 @@ pub mod root { #[derive(Debug)] pub struct gfxFontFeatureValueSet_ValueList { pub name: ::nsstring::nsStringRepr, - pub featureSelectors: root::nsTArray<::std::os::raw::c_uint>, + pub featureSelectors: root::nsTArray, } #[test] fn bindgen_test_layout_gfxFontFeatureValueSet_ValueList() { @@ -12431,7 +12502,7 @@ pub mod root { pub struct gfxFontFeatureValueSet_FeatureValueHashEntry { pub _base: root::PLDHashEntryHdr, pub mKey: root::gfxFontFeatureValueSet_FeatureValueHashKey, - pub mValues: root::nsTArray<::std::os::raw::c_uint>, + pub mValues: root::nsTArray, } pub type gfxFontFeatureValueSet_FeatureValueHashEntry_KeyType = *const root::gfxFontFeatureValueSet_FeatureValueHashKey; @@ -12536,7 +12607,7 @@ pub mod root { pub alternateValues: root::nsTArray, pub featureValueLookup: root::RefPtr, pub fontFeatureSettings: root::nsTArray, - pub fontVariationSettings: root::nsTArray, + pub fontVariationSettings: root::nsTArray, pub languageOverride: u32, } #[test] @@ -15494,7 +15565,7 @@ pub mod root { /// tracking. NOTE: A string buffer can be modified only if its reference /// count is 1. #[repr(C)] - #[derive(Debug, Copy)] + #[derive(Debug)] pub struct nsStringBuffer { pub mRefCount: u32, pub mStorageSize: u32, @@ -15516,9 +15587,6 @@ pub mod root { "Alignment of field: " , stringify ! ( nsStringBuffer ) , "::" , stringify ! ( mStorageSize ) )); } - impl Clone for nsStringBuffer { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug, Copy)] pub struct nsIAtom { @@ -15535,6 +15603,13 @@ pub mod root { pub struct nsIAtom_COMTypeInfo { pub _address: u8, } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsIAtom_AtomKind { + DynamicAtom = 0, + StaticAtom = 1, + HTML5Atom = 2, + } #[test] fn bindgen_test_layout_nsIAtom() { assert_eq!(::std::mem::size_of::() , 24usize , concat ! ( @@ -15567,13 +15642,13 @@ pub mod root { *mut u32 as *mut u8, ::std::mem::size_of::()) }; - let mask = 2147483647u64 as u32; + let mask = 1073741823u64 as u32; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_mLength(&mut self, val: u32) { - let mask = 2147483647u64 as u32; + let mask = 1073741823u64 as u32; let val = val as u32 as u32; let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; @@ -15595,7 +15670,7 @@ pub mod root { } } #[inline] - pub fn mIsStatic(&self) -> u32 { + pub fn mKind(&self) -> u32 { let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -15605,13 +15680,13 @@ pub mod root { *mut u32 as *mut u8, ::std::mem::size_of::()) }; - let mask = 2147483648u64 as u32; - let val = (unit_field_val & mask) >> 31usize; + let mask = 3221225472u64 as u32; + let val = (unit_field_val & mask) >> 30usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] - pub fn set_mIsStatic(&mut self, val: u32) { - let mask = 2147483648u64 as u32; + pub fn set_mKind(&mut self, val: u32) { + let mask = 3221225472u64 as u32; let val = val as u32 as u32; let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; @@ -15623,7 +15698,7 @@ pub mod root { ::std::mem::size_of::()) }; unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; + unit_field_val |= (val << 30usize) & mask; unsafe { ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as *const u8, @@ -15633,14 +15708,12 @@ pub mod root { } } #[inline] - pub fn new_bitfield_1(mLength: u32, mIsStatic: u32) -> u32 { + pub fn new_bitfield_1(mLength: u32, mKind: u32) -> u32 { ({ ({ 0 } | ((mLength as u32 as u32) << 0usize) & - (2147483647u64 as u32)) - } | - ((mIsStatic as u32 as u32) << 31usize) & - (2147483648u64 as u32)) + (1073741823u64 as u32)) + } | ((mKind as u32 as u32) << 30usize) & (3221225472u64 as u32)) } } #[repr(C)] @@ -15804,6 +15877,9 @@ pub mod root { pub const nsIRequest_LOAD_HTML_OBJECT_DATA: root::nsIRequest__bindgen_ty_1 = nsIRequest__bindgen_ty_1::LOAD_HTML_OBJECT_DATA; + pub const nsIRequest_LOAD_DOCUMENT_NEEDS_COOKIE: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_DOCUMENT_NEEDS_COOKIE; pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = nsIRequest__bindgen_ty_1::INHIBIT_CACHING; pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: @@ -15832,6 +15908,7 @@ pub mod root { LOAD_NORMAL = 0, LOAD_BACKGROUND = 1, LOAD_HTML_OBJECT_DATA = 2, + LOAD_DOCUMENT_NEEDS_COOKIE = 4, INHIBIT_CACHING = 128, INHIBIT_PERSISTENT_CACHING = 256, LOAD_BYPASS_CACHE = 512, @@ -16895,7 +16972,7 @@ pub mod root { pub mUpgradeInsecurePreloads: bool, pub mHSTSPrimingURIList: [u64; 6usize], pub mDocumentContainer: u64, - pub mCharacterSet: root::mozilla::NotNull<*const root::mozilla::Encoding>, + pub mCharacterSet: root::mozilla::NotNull<*const root::nsIDocument_Encoding>, pub mCharacterSetSource: i32, pub mParentDocument: *mut root::nsIDocument, pub mCachedRootElement: *mut root::mozilla::dom::Element, @@ -16947,7 +17024,7 @@ pub mod root { /// The current frame request callback handle pub mFrameRequestCallbackCounter: i32, pub mStaticCloneCount: u32, - pub mBlockedTrackingNodes: root::nsTArray>, + pub mBlockedTrackingNodes: root::nsTArray, pub mWindow: *mut root::nsPIDOMWindowInner, pub mCachedEncoder: root::nsCOMPtr, pub mFrameRequestCallbacks: root::nsTArray, @@ -19055,7 +19132,7 @@ pub mod root { } } #[inline] - pub fn mIsScopedStyleEnabled(&self) -> ::std::os::raw::c_uint { + pub fn mMightHaveStaleServoData(&self) -> bool { let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -19065,15 +19142,14 @@ pub mod root { *mut u64 as *mut u8, ::std::mem::size_of::()) }; - let mask = 422212465065984u64 as u64; + let mask = 140737488355328u64 as u64; let val = (unit_field_val & mask) >> 47usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(val as u8) } } #[inline] - pub fn set_mIsScopedStyleEnabled(&mut self, - val: ::std::os::raw::c_uint) { - let mask = 422212465065984u64 as u64; - let val = val as u32 as u64; + pub fn set_mMightHaveStaleServoData(&mut self, val: bool) { + let mask = 140737488355328u64 as u64; + let val = val as u8 as u64; let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -19094,6 +19170,45 @@ pub mod root { } } #[inline] + pub fn mIsScopedStyleEnabled(&self) -> ::std::os::raw::c_uint { + let mut unit_field_val: u64 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as + *mut u64 as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 844424930131968u64 as u64; + let val = (unit_field_val & mask) >> 48usize; + unsafe { ::std::mem::transmute(val as u32) } + } + #[inline] + pub fn set_mIsScopedStyleEnabled(&mut self, + val: ::std::os::raw::c_uint) { + let mask = 844424930131968u64 as u64; + let val = val as u32 as u64; + let mut unit_field_val: u64 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as + *mut u64 as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 48usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] pub fn new_bitfield_1(mBidiEnabled: bool, mMathMLEnabled: bool, mIsInitialDocumentInWindow: bool, mIgnoreDocGroupMismatches: bool, @@ -19136,6 +19251,7 @@ pub mod root { mFrameRequestCallbacksScheduled: bool, mIsTopLevelContentDocument: bool, mIsContentDocument: bool, + mMightHaveStaleServoData: bool, mIsScopedStyleEnabled: ::std::os::raw::c_uint) -> u64 { ({ @@ -19186,542 +19302,555 @@ pub mod root { ({ ({ ({ - 0 + ({ + 0 + } + | + ((mBidiEnabled + as + u8 + as + u64) + << + 0usize) + & + (1u64 + as + u64)) } | - ((mBidiEnabled + ((mMathMLEnabled as u8 as u64) << - 0usize) + 1usize) & - (1u64 + (2u64 as u64)) } | - ((mMathMLEnabled + ((mIsInitialDocumentInWindow as u8 as u64) << - 1usize) + 2usize) & - (2u64 + (4u64 as u64)) } | - ((mIsInitialDocumentInWindow + ((mIgnoreDocGroupMismatches as u8 as u64) << - 2usize) + 3usize) & - (4u64 + (8u64 as u64)) } | - ((mIgnoreDocGroupMismatches + ((mLoadedAsData as u8 as u64) << - 3usize) + 4usize) & - (8u64 + (16u64 as u64)) } | - ((mLoadedAsData + ((mLoadedAsInteractiveData as u8 as u64) << - 4usize) + 5usize) & - (16u64 + (32u64 as u64)) } | - ((mLoadedAsInteractiveData + ((mMayStartLayout as u8 as u64) << - 5usize) + 6usize) & - (32u64 + (64u64 as u64)) } | - ((mMayStartLayout + ((mHaveFiredTitleChange as u8 as u64) << - 6usize) + 7usize) & - (64u64 + (128u64 as u64)) } | - ((mHaveFiredTitleChange + ((mIsShowing as u8 as u64) << - 7usize) + 8usize) & - (128u64 + (256u64 as u64)) } | - ((mIsShowing + ((mVisible as u8 as u64) << - 8usize) + 9usize) & - (256u64 + (512u64 as u64)) } | - ((mVisible + ((mHasReferrerPolicyCSP as u8 as u64) << - 9usize) + 10usize) & - (512u64 + (1024u64 as u64)) } | - ((mHasReferrerPolicyCSP + ((mRemovedFromDocShell as u8 as u64) << - 10usize) + 11usize) & - (1024u64 + (2048u64 as u64)) } | - ((mRemovedFromDocShell + ((mAllowDNSPrefetch as u8 as u64) << - 11usize) + 12usize) & - (2048u64 + (4096u64 as u64)) } | - ((mAllowDNSPrefetch + ((mIsStaticDocument as u8 as u64) << - 12usize) + 13usize) & - (4096u64 + (8192u64 as u64)) } | - ((mIsStaticDocument + ((mCreatingStaticClone as u8 as u64) << - 13usize) + 14usize) & - (8192u64 + (16384u64 as u64)) } | - ((mCreatingStaticClone + ((mInUnlinkOrDeletion as u8 as u64) << - 14usize) + 15usize) & - (16384u64 + (32768u64 as u64)) } | - ((mInUnlinkOrDeletion + ((mHasHadScriptHandlingObject as u8 as u64) << - 15usize) + 16usize) & - (32768u64 + (65536u64 as u64)) } | - ((mHasHadScriptHandlingObject + ((mIsBeingUsedAsImage as u8 as u64) << - 16usize) + 17usize) & - (65536u64 + (131072u64 as u64)) } | - ((mIsBeingUsedAsImage + ((mIsSyntheticDocument as u8 as u64) << - 17usize) + 18usize) & - (131072u64 + (262144u64 as u64)) } | - ((mIsSyntheticDocument + ((mHasLinksToUpdate as u8 as u64) << - 18usize) + 19usize) & - (262144u64 + (524288u64 as u64)) } | - ((mHasLinksToUpdate + ((mHasLinksToUpdateRunnable as u8 as u64) << - 19usize) + 20usize) & - (524288u64 + (1048576u64 as u64)) } | - ((mHasLinksToUpdateRunnable + ((mMayHaveDOMMutationObservers as u8 as u64) << - 20usize) + 21usize) & - (1048576u64 + (2097152u64 as u64)) } | - ((mMayHaveDOMMutationObservers + ((mMayHaveAnimationObservers as u8 as u64) << - 21usize) + 22usize) & - (2097152u64 + (4194304u64 as u64)) } | - ((mMayHaveAnimationObservers + ((mHasMixedActiveContentLoaded as u8 as u64) << - 22usize) + 23usize) & - (4194304u64 + (8388608u64 as u64)) } | - ((mHasMixedActiveContentLoaded + ((mHasMixedActiveContentBlocked as u8 as u64) << - 23usize) + 24usize) & - (8388608u64 + (16777216u64 as u64)) } | - ((mHasMixedActiveContentBlocked + ((mHasMixedDisplayContentLoaded as u8 as u64) << - 24usize) + 25usize) & - (16777216u64 + (33554432u64 as u64)) } | - ((mHasMixedDisplayContentLoaded + ((mHasMixedDisplayContentBlocked as u8 as u64) << - 25usize) + 26usize) & - (33554432u64 + (67108864u64 as u64)) } | - ((mHasMixedDisplayContentBlocked + ((mHasMixedContentObjectSubrequest as u8 as u64) << - 26usize) + 27usize) & - (67108864u64 + (134217728u64 as u64)) } | - ((mHasMixedContentObjectSubrequest + ((mHasCSP as u8 as u64) << - 27usize) + 28usize) & - (134217728u64 + (268435456u64 as u64)) } | - ((mHasCSP + ((mHasUnsafeEvalCSP as u8 as u64) << - 28usize) + 29usize) & - (268435456u64 + (536870912u64 as u64)) } | - ((mHasUnsafeEvalCSP + ((mHasUnsafeInlineCSP as u8 as u64) << - 29usize) + 30usize) & - (536870912u64 + (1073741824u64 as u64)) } | - ((mHasUnsafeInlineCSP + ((mHasTrackingContentBlocked as u8 as u64) << - 30usize) + 31usize) & - (1073741824u64 + (2147483648u64 as u64)) } | - ((mHasTrackingContentBlocked + ((mHasTrackingContentLoaded as u8 as u64) << - 31usize) + 32usize) & - (2147483648u64 + (4294967296u64 as u64)) } | - ((mHasTrackingContentLoaded + ((mBFCacheDisallowed as u8 as u64) << - 32usize) + 33usize) & - (4294967296u64 + (8589934592u64 as u64)) } | - ((mBFCacheDisallowed + ((mHasHadDefaultView as u8 as u64) << - 33usize) + 34usize) & - (8589934592u64 + (17179869184u64 as u64)) } | - ((mHasHadDefaultView + ((mStyleSheetChangeEventsEnabled as u8 as u64) << - 34usize) + 35usize) & - (17179869184u64 + (34359738368u64 as u64)) } | - ((mStyleSheetChangeEventsEnabled + ((mIsSrcdocDocument as u8 as u64) << - 35usize) + 36usize) & - (34359738368u64 + (68719476736u64 as u64)) } | - ((mIsSrcdocDocument + ((mDidDocumentOpen as u8 as u64) << - 36usize) + 37usize) & - (68719476736u64 + (137438953472u64 as u64)) } | - ((mDidDocumentOpen + ((mHasDisplayDocument as u8 as u64) << - 37usize) + 38usize) & - (137438953472u64 + (274877906944u64 as u64)) } | - ((mHasDisplayDocument + ((mFontFaceSetDirty as u8 as u64) << - 38usize) & - (274877906944u64 + 39usize) & + (549755813888u64 as u64)) } | - ((mFontFaceSetDirty + ((mGetUserFontSetCalled as u8 as u64) - << 39usize) & - (549755813888u64 + << 40usize) & + (1099511627776u64 as u64)) } | - ((mGetUserFontSetCalled as - u8 as u64) << - 40usize) & - (1099511627776u64 as + ((mPostedFlushUserFontSet + as u8 as u64) << + 41usize) & + (2199023255552u64 as u64)) } | - ((mPostedFlushUserFontSet as u8 - as u64) << 41usize) & - (2199023255552u64 as u64)) + ((mDidFireDOMContentLoaded as + u8 as u64) << 42usize) & + (4398046511104u64 as u64)) } | - ((mDidFireDOMContentLoaded as u8 as - u64) << 42usize) & - (4398046511104u64 as u64)) + ((mHasScrollLinkedEffect as u8 as + u64) << 43usize) & + (8796093022208u64 as u64)) } | - ((mHasScrollLinkedEffect as u8 as u64) << - 43usize) & - (8796093022208u64 as u64)) + ((mFrameRequestCallbacksScheduled as u8 + as u64) << 44usize) & + (17592186044416u64 as u64)) } | - ((mFrameRequestCallbacksScheduled as u8 as - u64) << 44usize) & - (17592186044416u64 as u64)) + ((mIsTopLevelContentDocument as u8 as u64) << + 45usize) & (35184372088832u64 as u64)) } | - ((mIsTopLevelContentDocument as u8 as u64) << - 45usize) & (35184372088832u64 as u64)) + ((mIsContentDocument as u8 as u64) << 46usize) & + (70368744177664u64 as u64)) } | - ((mIsContentDocument as u8 as u64) << 46usize) & - (70368744177664u64 as u64)) + ((mMightHaveStaleServoData as u8 as u64) << 47usize) & + (140737488355328u64 as u64)) } | - ((mIsScopedStyleEnabled as u32 as u64) << 47usize) & - (422212465065984u64 as u64)) + ((mIsScopedStyleEnabled as u32 as u64) << 48usize) & + (844424930131968u64 as u64)) } } #[repr(C)] @@ -19736,7 +19865,7 @@ pub mod root { pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub _mOwningThread: root::nsAutoOwningThread, pub mBoundContentSet: u64, - pub mWrapperTable: u64, + pub mWrapperTable: root::nsAutoPtr, pub mDocumentTable: u64, pub mLoadingDocTable: u64, pub mAttachedStack: root::nsBindingList, @@ -20022,7 +20151,6 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct nsStyleContext { - pub mParent: root::RefPtr, pub mPseudoTag: root::nsCOMPtr, pub mBits: u64, pub mFrameRefCnt: u32, @@ -20041,28 +20169,23 @@ pub mod root { } #[test] fn bindgen_test_layout_nsStyleContext() { - assert_eq!(::std::mem::size_of::() , 32usize , concat + assert_eq!(::std::mem::size_of::() , 24usize , concat ! ( "Size of: " , stringify ! ( nsStyleContext ) )); assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsStyleContext ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const nsStyleContext ) ) . mParent as * - const _ as usize } , 0usize , concat ! ( - "Alignment of field: " , stringify ! ( nsStyleContext ) , - "::" , stringify ! ( mParent ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleContext ) ) . mPseudoTag as * - const _ as usize } , 8usize , concat ! ( + const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleContext ) , "::" , stringify ! ( mPseudoTag ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleContext ) ) . mBits as * const - _ as usize } , 16usize , concat ! ( + _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleContext ) , "::" , stringify ! ( mBits ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleContext ) ) . mFrameRefCnt as - * const _ as usize } , 24usize , concat ! ( + * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleContext ) , "::" , stringify ! ( mFrameRefCnt ) )); } @@ -23565,7 +23688,7 @@ pub mod root { pub _base_1: root::nsWrapperCache, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub _mOwningThread: root::nsAutoOwningThread, - pub mContent: root::nsCOMPtr, + pub mContent: root::nsCOMPtr, /// Cache of Attrs. pub mAttributeCache: root::nsDOMAttributeMap_AttrCache, } @@ -24944,57 +25067,57 @@ pub mod root { pub struct nsRange { _unused: [u8; 0], } - pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_LISTENERMANAGER; - pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_PROPERTIES; - pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_ANONYMOUS_ROOT; - pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; - pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_NATIVE_ANONYMOUS_ROOT; - pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_FORCE_XBL_BINDINGS; - pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_MAY_BE_IN_BINDING_MNGR; - pub const NODE_IS_EDITABLE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_EDITABLE; - pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_NATIVE_ANONYMOUS; - pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_IN_SHADOW_TREE; - pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_EMPTY_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_SLOW_SELECTOR; - pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_EDGE_CHILD_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; - pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_ALL_SELECTOR_FLAGS; - pub const NODE_NEEDS_FRAME: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_NEEDS_FRAME; - pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_DESCENDANTS_NEED_FRAMES; - pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_ACCESSKEY; - pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_DIRECTION_RTL; - pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_DIRECTION_LTR; - pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_ALL_DIRECTION_FLAGS; - pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_CHROME_ONLY_ACCESS; - pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; - pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_TYPE_SPECIFIC_BITS_OFFSET; + pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_LISTENERMANAGER; + pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_PROPERTIES; + pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_ANONYMOUS_ROOT; + pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; + pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS_ROOT; + pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_FORCE_XBL_BINDINGS; + pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_MAY_BE_IN_BINDING_MNGR; + pub const NODE_IS_EDITABLE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_EDITABLE; + pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS; + pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_IN_SHADOW_TREE; + pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_EMPTY_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR; + pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_EDGE_CHILD_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; + pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_ALL_SELECTOR_FLAGS; + pub const NODE_NEEDS_FRAME: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_NEEDS_FRAME; + pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_DESCENDANTS_NEED_FRAMES; + pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_ACCESSKEY; + pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_DIRECTION_RTL; + pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_DIRECTION_LTR; + pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_ALL_DIRECTION_FLAGS; + pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_CHROME_ONLY_ACCESS; + pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; + pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_18 { + pub enum _bindgen_ty_77 { NODE_HAS_LISTENERMANAGER = 4, NODE_HAS_PROPERTIES = 8, NODE_IS_ANONYMOUS_ROOT = 16, @@ -28720,7 +28843,7 @@ pub mod root { pub mRefCnt: root::nsAutoRefCnt, pub _mOwningThread: root::nsAutoOwningThread, pub mBehaviour: root::mozilla::UniquePtr, - pub mURI: root::RefPtr, + pub mURI: root::RefPtr, pub mListener: *mut root::imgINotificationObserver, pub mLoadGroup: root::nsCOMPtr, pub mTabGroup: root::RefPtr, @@ -29764,9 +29887,6 @@ pub mod root { "Alignment of field: " , stringify ! ( nsCSSValue_Array ) , "::" , stringify ! ( mArray ) )); } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsCSSValue_Serialization { eNormalized = 0, } #[repr(C)] #[derive(Debug, Copy)] pub struct nsCSSValue__bindgen_ty_1 { @@ -31902,7 +32022,7 @@ pub mod root { pub type RawGeckoPropertyValuePairList = root::nsTArray; pub type RawGeckoComputedKeyframeValuesList = - root::nsTArray>; + root::nsTArray; pub type RawGeckoStyleAnimationList = root::nsStyleAutoArray; pub type RawGeckoFontFaceRuleList = @@ -32575,46 +32695,46 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISMILAttr ) )); } - pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; pub const ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO: - root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_20 + root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_79 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; pub const ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT: - root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; - pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_PENDING_RESTYLE_FLAGS; - pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; - pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_ALL_RESTYLE_FLAGS; - pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; + root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; + pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_PENDING_RESTYLE_FLAGS; + pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; + pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_ALL_RESTYLE_FLAGS; + pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_20 { + pub enum _bindgen_ty_79 { ELEMENT_SHARED_RESTYLE_BIT_1 = 8388608, ELEMENT_SHARED_RESTYLE_BIT_2 = 16777216, ELEMENT_SHARED_RESTYLE_BIT_3 = 33554432, @@ -33211,7 +33331,7 @@ pub mod root { "::" , stringify ! ( mArray ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char16_t_close0_instantiation() { + fn __bindgen_test_layout_nsCharTraits_open0_nsStringRepr_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33222,62 +33342,33 @@ pub mod root { root::nsCharTraits ) )); } #[test] - fn __bindgen_test_layout_nsReadingIterator_open0_char16_t_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 24usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsReadingIterator ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsReadingIterator ) )); - } - #[test] - fn __bindgen_test_layout_nsWritingIterator_open0_char16_t_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 24usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsWritingIterator ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsWritingIterator ) )); - } - #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 1usize , - concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsCharTraits ) )); - assert_eq!(::std::mem::align_of::() , 1usize , - concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsCharTraits ) )); - } - #[test] - fn __bindgen_test_layout_nsReadingIterator_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsReadingIterator_open0_nsStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 24usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsReadingIterator<::std::os::raw::c_char> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsReadingIterator + ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsReadingIterator<::std::os::raw::c_char> ) )); + root::nsReadingIterator + ) )); } #[test] - fn __bindgen_test_layout_nsWritingIterator_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsWritingIterator_open0_nsStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 24usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsWritingIterator<::std::os::raw::c_char> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsWritingIterator + ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsWritingIterator<::std::os::raw::c_char> ) )); + root::nsWritingIterator + ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char16_t_close0_instantiation_1() { + fn __bindgen_test_layout_nsCharTraits_open0_nsCStringRepr_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33288,7 +33379,44 @@ pub mod root { root::nsCharTraits ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char_close0_instantiation_1() { + fn __bindgen_test_layout_nsReadingIterator_open0_nsCStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 24usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsReadingIterator + ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsReadingIterator + ) )); + } + #[test] + fn __bindgen_test_layout_nsWritingIterator_open0_nsCStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 24usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsWritingIterator + ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsWritingIterator + ) )); + } + #[test] + fn __bindgen_test_layout_nsCharTraits_open0_nsSubstringTuple_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::() , 1usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsCharTraits ) )); + assert_eq!(::std::mem::align_of::() , 1usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsCharTraits ) )); + } + #[test] + fn __bindgen_test_layout_nsCharTraits_open0_nsCSubstringTuple_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33389,26 +33517,26 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxFontFeatureValueSet_ValueList_close0_instantiation() { @@ -33424,26 +33552,26 @@ pub mod root { )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_2() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxAlternateValue_close0_instantiation() { @@ -33479,18 +33607,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_203903_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_201937_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33758,6 +33886,17 @@ pub mod root { root::RefPtr ) )); } #[test] + fn __bindgen_test_layout_RefPtr_open0_ServoStyleContext_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::RefPtr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_1() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -33780,7 +33919,7 @@ pub mod root { root::mozilla::binding_danger::TErrorResult ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_205688_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_203731_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33941,7 +34080,7 @@ pub mod root { root::JS::DeletePolicy ) )); } #[test] - fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_211246__bindgen_ty_id_211253_close0_instantiation() { + fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_209318__bindgen_ty_id_209325_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34167,15 +34306,15 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_213736_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211794_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::nsIDocument_Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); + root::nsTArray<*mut root::nsIDocument_Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation() { @@ -34235,15 +34374,15 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214038_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212096_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::nsIDocument_Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); + root::nsTArray<*mut root::nsIDocument_Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation_1() { @@ -34347,16 +34486,16 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_214580_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_212638_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::mozilla::Encoding> ) + root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) )); - assert_eq!(::std::mem::align_of::>() + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::mozilla::Encoding> ) + root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) )); } #[test] @@ -34558,28 +34697,15 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCOMPtr_open1_nsIWeakReference_close1_close0_instantiation() { - assert_eq!(::std::mem::size_of::>>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsWeakPtr_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , + 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray> ) - )); - assert_eq!(::std::mem::align_of::>>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , + 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray> ) - )); - } - #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIDocumentEncoder_close0_instantiation() { @@ -34729,7 +34855,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214995_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_213050_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34819,7 +34945,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_215401_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_213449_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34920,7 +35046,7 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216375_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214420_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34951,13 +35077,17 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsAutoPtr_open0_nsInterfaceHashtable_open1_nsISupportsHashKey_nsIXPConnectWrappedJS_close1_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( u64 ) + fn __bindgen_test_layout_nsAutoPtr_open0_nsBindingManager_WrapperHashtable_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsAutoPtr ) )); - assert_eq!(::std::mem::align_of::() , 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - u64 ) )); + root::nsAutoPtr ) + )); } #[test] fn __bindgen_test_layout_nsAutoPtr_open0_nsRefPtrHashtable_open1_nsURIHashKey_nsXBLDocumentInfo_close1_close0_instantiation() { @@ -35009,7 +35139,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216680_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214722_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35020,7 +35150,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216685_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214727_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35031,17 +35161,6 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_nsStyleContext_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); - } - #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIAtom_close0_instantiation_3() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35088,7 +35207,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_217178_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_215218_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35466,15 +35585,15 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_Element_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsCOMPtr_open0_nsDOMAttributeMap_Element_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); - assert_eq!(::std::mem::align_of::>() + root::nsCOMPtr ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); + root::nsCOMPtr ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_StyleSheet_close1_close0_instantiation_3() { @@ -35725,7 +35844,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation_1() { + fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35736,7 +35855,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_220037_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_218077_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35815,7 +35934,7 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226379_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224369_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35848,7 +35967,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_227540_close0_instantiation() { + fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_225530_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35859,7 +35978,7 @@ pub mod root { root::JS::Heap<*mut root::JSObject> ) )); } #[test] - fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_227544_close0_instantiation() { + fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_225534_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35881,7 +36000,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_TenuredHeap_open0__bindgen_ty_id_227551_close0_instantiation() { + fn __bindgen_test_layout_TenuredHeap_open0__bindgen_ty_id_225541_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35960,7 +36079,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_229008_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226720_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36155,7 +36274,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230383_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228168_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36260,7 +36379,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_232806_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230585_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36405,15 +36524,15 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_ImageURL_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_RefPtr_open0_imgRequestProxy_ImageURL_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); + root::RefPtr ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsILoadGroup_close0_instantiation() { @@ -36961,7 +37080,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_235361_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_233132_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37198,7 +37317,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243166_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240831_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37209,7 +37328,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243171_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240836_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37297,7 +37416,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243284_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240949_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37584,7 +37703,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_244896_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242540_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37606,7 +37725,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_245058_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242700_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37617,7 +37736,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_245063_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242705_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37639,6 +37758,17 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_17() { + assert_eq!(::std::mem::size_of::>() , + 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTArray<::nsstring::nsStringRepr> ) )); + assert_eq!(::std::mem::align_of::>() , + 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTArray<::nsstring::nsStringRepr> ) )); + } + #[test] fn __bindgen_test_layout_RefPtr_open0_RawServoMediaList_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -37683,18 +37813,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_247114_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_244775_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37705,7 +37835,7 @@ pub mod root { root::nsTArray<*mut root::mozilla::css::DocumentRule> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_247122_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_244783_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( diff --git a/servo/components/style/gecko/generated/structs_release.rs b/servo/components/style/gecko/generated/structs_release.rs index 9a8144f55ebe..1ea4be46809e 100644 --- a/servo/components/style/gecko/generated/structs_release.rs +++ b/servo/components/style/gecko/generated/structs_release.rs @@ -1052,7 +1052,8 @@ pub mod root { } pub type pair_first_type<_T1> = _T1; pub type pair_second_type<_T2> = _T2; - pub type conditional_type<_If> = _If; + pub type pair__PCCP = u8; + pub type pair__PCCFP = u8; #[repr(C)] #[derive(Debug, Copy)] pub struct input_iterator_tag { @@ -1072,113 +1073,32 @@ pub mod root { fn clone(&self) -> Self { *self } } #[repr(C)] - #[derive(Debug, Copy)] - pub struct forward_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_forward_iterator_tag() { - assert_eq!(::std::mem::size_of::() , 1usize - , concat ! ( - "Size of: " , stringify ! ( forward_iterator_tag ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( forward_iterator_tag ) - )); - } - impl Clone for forward_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct bidirectional_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_bidirectional_iterator_tag() { - assert_eq!(::std::mem::size_of::() , - 1usize , concat ! ( - "Size of: " , stringify ! ( bidirectional_iterator_tag - ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( - bidirectional_iterator_tag ) )); - } - impl Clone for bidirectional_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy)] - pub struct random_access_iterator_tag { - pub _address: u8, - } - #[test] - fn bindgen_test_layout_random_access_iterator_tag() { - assert_eq!(::std::mem::size_of::() , - 1usize , concat ! ( - "Size of: " , stringify ! ( random_access_iterator_tag - ) )); - assert_eq! (::std::mem::align_of::() , - 1usize , concat ! ( - "Alignment of " , stringify ! ( - random_access_iterator_tag ) )); - } - impl Clone for random_access_iterator_tag { - fn clone(&self) -> Self { *self } - } - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct iterator { pub _address: u8, } + pub type iterator_iterator_category<_Category> = _Category; pub type iterator_value_type<_Tp> = _Tp; pub type iterator_difference_type<_Distance> = _Distance; pub type iterator_pointer<_Pointer> = _Pointer; pub type iterator_reference<_Reference> = _Reference; - pub type iterator_iterator_category<_Category> = _Category; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct atomic { } - pub type atomic___base = u8; - pub type __bit_iterator_difference_type = [u8; 0usize]; - pub type __bit_iterator_value_type = bool; - pub type __bit_iterator_pointer = u8; - pub type __bit_iterator_reference = u8; - pub type __bit_iterator_iterator_category = - root::std::random_access_iterator_tag; - pub type __bit_iterator___storage_type = [u8; 0usize]; - pub type __bit_iterator___storage_pointer = [u8; 0usize]; + pub type _Base_bitset__WordT = ::std::os::raw::c_ulong; + pub type bitset__Base = u8; + pub type bitset__WordT = ::std::os::raw::c_ulong; #[repr(C)] - pub struct __bit_const_reference { - pub __seg_: root::std::__bit_const_reference___storage_pointer, - pub __mask_: root::std::__bit_const_reference___storage_type, + #[derive(Debug)] + pub struct bitset_reference { + pub _M_wp: *mut root::std::bitset__WordT, + pub _M_bpos: usize, } - pub type __bit_const_reference___storage_type = [u8; 0usize]; - pub type __bit_const_reference___storage_pointer = [u8; 0usize]; - pub type __bit_reference___storage_type = [u8; 0usize]; - pub type __bit_reference___storage_pointer = [u8; 0usize]; - pub type __bitset_difference_type = isize; - pub type __bitset_size_type = usize; - pub type __bitset___storage_type = root::std::__bitset_size_type; - pub type __bitset___self = u8; - pub type __bitset___storage_pointer = - *mut root::std::__bitset___storage_type; - pub type __bitset___const_storage_pointer = - *const root::std::__bitset___storage_type; - pub const __bitset___bits_per_word: ::std::os::raw::c_uint = 64; - pub type __bitset_reference = u8; - pub type __bitset_const_reference = root::std::__bit_const_reference; - pub type __bitset_iterator = u8; - pub type __bitset_const_iterator = u8; - extern "C" { - #[link_name = "__n_words"] - pub static bitset___n_words: ::std::os::raw::c_uint; - } - pub type bitset_base = u8; - pub type bitset_reference = root::std::bitset_base; - pub type bitset_const_reference = root::std::bitset_base; + } + pub mod __gnu_cxx { + #[allow(unused_imports)] + use self::super::super::root; } pub mod mozilla { #[allow(unused_imports)] @@ -1225,8 +1145,9 @@ pub mod root { root::nsSubstringTuple; pub type nsStringRepr_string_type = ::nsstring::nsStringRepr; pub type nsStringRepr_const_iterator = - root::nsReadingIterator; - pub type nsStringRepr_iterator = root::nsWritingIterator; + root::nsReadingIterator; + pub type nsStringRepr_iterator = + root::nsWritingIterator; pub type nsStringRepr_comparator_type = root::nsStringComparator; pub type nsStringRepr_char_iterator = *mut root::mozilla::detail::nsStringRepr_char_type; @@ -1293,9 +1214,9 @@ pub mod root { root::nsCSubstringTuple; pub type nsCStringRepr_string_type = root::nsCString; pub type nsCStringRepr_const_iterator = - root::nsReadingIterator<::std::os::raw::c_char>; + root::nsReadingIterator; pub type nsCStringRepr_iterator = - root::nsWritingIterator<::std::os::raw::c_char>; + root::nsWritingIterator; pub type nsCStringRepr_comparator_type = root::nsCStringComparator; pub type nsCStringRepr_char_iterator = @@ -2235,7 +2156,7 @@ pub mod root { } } #[repr(C)] - #[derive(Debug, Copy)] + #[derive(Debug)] pub struct ThreadSafeAutoRefCnt { pub mValue: u64, } @@ -2256,9 +2177,6 @@ pub mod root { ThreadSafeAutoRefCnt ) , "::" , stringify ! ( mValue ) )); } - impl Clone for ThreadSafeAutoRefCnt { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug)] pub struct OwningNonNull { @@ -4963,6 +4881,7 @@ pub mod root { pub _base: root::nsStyleContext, pub mPresContext: *mut root::nsPresContext, pub mSource: root::ServoComputedData, + pub mNextInheritingAnonBoxStyle: root::RefPtr, } #[test] fn bindgen_test_layout_ServoStyleContext() { @@ -4975,17 +4894,24 @@ pub mod root { )); assert_eq! (unsafe { & ( * ( 0 as * const ServoStyleContext ) ) . - mPresContext as * const _ as usize } , 24usize , + mPresContext as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleContext ) , "::" , stringify ! ( mPresContext ) )); assert_eq! (unsafe { & ( * ( 0 as * const ServoStyleContext ) ) . mSource - as * const _ as usize } , 32usize , concat ! ( + as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleContext ) , "::" , stringify ! ( mSource ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const ServoStyleContext ) ) . + mNextInheritingAnonBoxStyle as * const _ as usize } , + 248usize , concat ! ( + "Alignment of field: " , stringify ! ( + ServoStyleContext ) , "::" , stringify ! ( + mNextInheritingAnonBoxStyle ) )); } #[repr(C)] #[derive(Debug)] @@ -6192,6 +6118,7 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( Runnable ) )); } + pub type Preferences_PrefSetting = root::mozilla::dom::PrefSetting; #[repr(C)] #[derive(Debug)] pub struct CycleCollectedJSContext_RunInMetastableStateData { @@ -6252,91 +6179,93 @@ pub mod root { eUseCounter_SVGSVGElement_currentScale_setter = 2, eUseCounter_property_Fill = 3, eUseCounter_property_FillOpacity = 4, - eUseCounter_PushManager_subscribe = 5, - eUseCounter_PushSubscription_unsubscribe = 6, - eUseCounter_Window_sidebar_getter = 7, - eUseCounter_Window_sidebar_setter = 8, - eUseCounter_External_addSearchEngine = 9, - eUseCounter_OfflineResourceList_swapCache = 10, - eUseCounter_OfflineResourceList_update = 11, - eUseCounter_OfflineResourceList_status_getter = 12, - eUseCounter_OfflineResourceList_status_setter = 13, - eUseCounter_OfflineResourceList_onchecking_getter = 14, - eUseCounter_OfflineResourceList_onchecking_setter = 15, - eUseCounter_OfflineResourceList_onerror_getter = 16, - eUseCounter_OfflineResourceList_onerror_setter = 17, - eUseCounter_OfflineResourceList_onnoupdate_getter = 18, - eUseCounter_OfflineResourceList_onnoupdate_setter = 19, - eUseCounter_OfflineResourceList_ondownloading_getter = 20, - eUseCounter_OfflineResourceList_ondownloading_setter = 21, - eUseCounter_OfflineResourceList_onprogress_getter = 22, - eUseCounter_OfflineResourceList_onprogress_setter = 23, - eUseCounter_OfflineResourceList_onupdateready_getter = 24, - eUseCounter_OfflineResourceList_onupdateready_setter = 25, - eUseCounter_OfflineResourceList_oncached_getter = 26, - eUseCounter_OfflineResourceList_oncached_setter = 27, - eUseCounter_OfflineResourceList_onobsolete_getter = 28, - eUseCounter_OfflineResourceList_onobsolete_setter = 29, - eUseCounter_IDBDatabase_createMutableFile = 30, - eUseCounter_IDBDatabase_mozCreateFileHandle = 31, - eUseCounter_IDBMutableFile_open = 32, - eUseCounter_IDBMutableFile_getFile = 33, - eUseCounter_DataTransfer_addElement = 34, - eUseCounter_DataTransfer_mozItemCount_getter = 35, - eUseCounter_DataTransfer_mozItemCount_setter = 36, - eUseCounter_DataTransfer_mozCursor_getter = 37, - eUseCounter_DataTransfer_mozCursor_setter = 38, - eUseCounter_DataTransfer_mozTypesAt = 39, - eUseCounter_DataTransfer_mozClearDataAt = 40, - eUseCounter_DataTransfer_mozSetDataAt = 41, - eUseCounter_DataTransfer_mozGetDataAt = 42, - eUseCounter_DataTransfer_mozUserCancelled_getter = 43, - eUseCounter_DataTransfer_mozUserCancelled_setter = 44, - eUseCounter_DataTransfer_mozSourceNode_getter = 45, - eUseCounter_DataTransfer_mozSourceNode_setter = 46, - eUseCounter_GetAttributeNode = 47, - eUseCounter_SetAttributeNode = 48, - eUseCounter_GetAttributeNodeNS = 49, - eUseCounter_SetAttributeNodeNS = 50, - eUseCounter_RemoveAttributeNode = 51, - eUseCounter_CreateAttribute = 52, - eUseCounter_CreateAttributeNS = 53, - eUseCounter_NodeValue = 54, - eUseCounter_TextContent = 55, - eUseCounter_EnablePrivilege = 56, - eUseCounter_DOMExceptionCode = 57, - eUseCounter_NoExposedProps = 58, - eUseCounter_MutationEvent = 59, - eUseCounter_Components = 60, - eUseCounter_PrefixedVisibilityAPI = 61, - eUseCounter_NodeIteratorDetach = 62, - eUseCounter_LenientThis = 63, - eUseCounter_GetPreventDefault = 64, - eUseCounter_GetSetUserData = 65, - eUseCounter_MozGetAsFile = 66, - eUseCounter_UseOfCaptureEvents = 67, - eUseCounter_UseOfReleaseEvents = 68, - eUseCounter_UseOfDOM3LoadMethod = 69, - eUseCounter_ChromeUseOfDOM3LoadMethod = 70, - eUseCounter_ShowModalDialog = 71, - eUseCounter_Window_Content = 72, - eUseCounter_SyncXMLHttpRequest = 73, - eUseCounter_Window_Cc_ontrollers = 74, - eUseCounter_ImportXULIntoContent = 75, - eUseCounter_PannerNodeDoppler = 76, - eUseCounter_NavigatorGetUserMedia = 77, - eUseCounter_WebrtcDeprecatedPrefix = 78, - eUseCounter_RTCPeerConnectionGetStreams = 79, - eUseCounter_AppCache = 80, - eUseCounter_PrefixedImageSmoothingEnabled = 81, - eUseCounter_PrefixedFullscreenAPI = 82, - eUseCounter_LenientSetter = 83, - eUseCounter_FileLastModifiedDate = 84, - eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap = 85, - eUseCounter_URLCreateObjectURL_MediaStream = 86, - eUseCounter_XMLBaseAttribute = 87, - eUseCounter_XMLBaseAttributeForStyleAttr = 88, - eUseCounter_Count = 89, + eUseCounter_XMLDocument_async_getter = 5, + eUseCounter_XMLDocument_async_setter = 6, + eUseCounter_PushManager_subscribe = 7, + eUseCounter_PushSubscription_unsubscribe = 8, + eUseCounter_Window_sidebar_getter = 9, + eUseCounter_Window_sidebar_setter = 10, + eUseCounter_External_addSearchEngine = 11, + eUseCounter_OfflineResourceList_swapCache = 12, + eUseCounter_OfflineResourceList_update = 13, + eUseCounter_OfflineResourceList_status_getter = 14, + eUseCounter_OfflineResourceList_status_setter = 15, + eUseCounter_OfflineResourceList_onchecking_getter = 16, + eUseCounter_OfflineResourceList_onchecking_setter = 17, + eUseCounter_OfflineResourceList_onerror_getter = 18, + eUseCounter_OfflineResourceList_onerror_setter = 19, + eUseCounter_OfflineResourceList_onnoupdate_getter = 20, + eUseCounter_OfflineResourceList_onnoupdate_setter = 21, + eUseCounter_OfflineResourceList_ondownloading_getter = 22, + eUseCounter_OfflineResourceList_ondownloading_setter = 23, + eUseCounter_OfflineResourceList_onprogress_getter = 24, + eUseCounter_OfflineResourceList_onprogress_setter = 25, + eUseCounter_OfflineResourceList_onupdateready_getter = 26, + eUseCounter_OfflineResourceList_onupdateready_setter = 27, + eUseCounter_OfflineResourceList_oncached_getter = 28, + eUseCounter_OfflineResourceList_oncached_setter = 29, + eUseCounter_OfflineResourceList_onobsolete_getter = 30, + eUseCounter_OfflineResourceList_onobsolete_setter = 31, + eUseCounter_IDBDatabase_createMutableFile = 32, + eUseCounter_IDBDatabase_mozCreateFileHandle = 33, + eUseCounter_IDBMutableFile_open = 34, + eUseCounter_IDBMutableFile_getFile = 35, + eUseCounter_DataTransfer_addElement = 36, + eUseCounter_DataTransfer_mozItemCount_getter = 37, + eUseCounter_DataTransfer_mozItemCount_setter = 38, + eUseCounter_DataTransfer_mozCursor_getter = 39, + eUseCounter_DataTransfer_mozCursor_setter = 40, + eUseCounter_DataTransfer_mozTypesAt = 41, + eUseCounter_DataTransfer_mozClearDataAt = 42, + eUseCounter_DataTransfer_mozSetDataAt = 43, + eUseCounter_DataTransfer_mozGetDataAt = 44, + eUseCounter_DataTransfer_mozUserCancelled_getter = 45, + eUseCounter_DataTransfer_mozUserCancelled_setter = 46, + eUseCounter_DataTransfer_mozSourceNode_getter = 47, + eUseCounter_DataTransfer_mozSourceNode_setter = 48, + eUseCounter_GetAttributeNode = 49, + eUseCounter_SetAttributeNode = 50, + eUseCounter_GetAttributeNodeNS = 51, + eUseCounter_SetAttributeNodeNS = 52, + eUseCounter_RemoveAttributeNode = 53, + eUseCounter_CreateAttribute = 54, + eUseCounter_CreateAttributeNS = 55, + eUseCounter_NodeValue = 56, + eUseCounter_TextContent = 57, + eUseCounter_EnablePrivilege = 58, + eUseCounter_DOMExceptionCode = 59, + eUseCounter_NoExposedProps = 60, + eUseCounter_MutationEvent = 61, + eUseCounter_Components = 62, + eUseCounter_PrefixedVisibilityAPI = 63, + eUseCounter_NodeIteratorDetach = 64, + eUseCounter_LenientThis = 65, + eUseCounter_GetPreventDefault = 66, + eUseCounter_GetSetUserData = 67, + eUseCounter_MozGetAsFile = 68, + eUseCounter_UseOfCaptureEvents = 69, + eUseCounter_UseOfReleaseEvents = 70, + eUseCounter_UseOfDOM3LoadMethod = 71, + eUseCounter_ChromeUseOfDOM3LoadMethod = 72, + eUseCounter_ShowModalDialog = 73, + eUseCounter_Window_Content = 74, + eUseCounter_SyncXMLHttpRequest = 75, + eUseCounter_Window_Cc_ontrollers = 76, + eUseCounter_ImportXULIntoContent = 77, + eUseCounter_PannerNodeDoppler = 78, + eUseCounter_NavigatorGetUserMedia = 79, + eUseCounter_WebrtcDeprecatedPrefix = 80, + eUseCounter_RTCPeerConnectionGetStreams = 81, + eUseCounter_AppCache = 82, + eUseCounter_PrefixedImageSmoothingEnabled = 83, + eUseCounter_PrefixedFullscreenAPI = 84, + eUseCounter_LenientSetter = 85, + eUseCounter_FileLastModifiedDate = 86, + eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap = 87, + eUseCounter_URLCreateObjectURL_MediaStream = 88, + eUseCounter_XMLBaseAttribute = 89, + eUseCounter_XMLBaseAttributeForStyleAttr = 90, + eUseCounter_Count = 91, } #[repr(C)] #[derive(Debug)] @@ -8196,6 +8125,8 @@ pub mod root { PropertyStyleAnimationValuePair ) , "::" , stringify ! ( mValue ) )); } + pub type ComputedKeyframeValues = + root::nsTArray; #[test] fn __bindgen_test_layout_DefaultDelete_open0_RawServoStyleSet_close0_instantiation() { assert_eq!(::std::mem::size_of::() , @@ -9787,6 +9718,7 @@ pub mod root { NS_ERROR_TRACKING_URI = 2153578530, NS_ERROR_UNWANTED_URI = 2153578531, NS_ERROR_BLOCKED_URI = 2153578533, + NS_ERROR_HARMFUL_URI = 2153578534, NS_ERROR_SAVE_LINK_AS_TIMEOUT = 2153578528, NS_ERROR_PARSED_DATA_CACHED = 2153578529, NS_REFRESHURI_HEADER_FOUND = 6094850, @@ -11303,6 +11235,11 @@ pub mod root { AutoSetAsyncStackForNewCalls ) , "::" , stringify ! ( oldAsyncCallIsExplicit ) )); } + pub type WarningReporter = + ::std::option::Option; #[repr(C)] #[derive(Debug)] pub struct AutoHideScriptedCaller { @@ -11400,6 +11337,140 @@ pub mod root { pub struct JSCompartment { _unused: [u8; 0], } + /// Describes a single error or warning that occurs in the execution of script. + #[repr(C)] + #[derive(Debug)] + pub struct JSErrorReport { + pub _base: root::JSErrorBase, + pub linebuf_: *const u16, + pub linebufLength_: usize, + pub tokenOffset_: usize, + pub notes: root::mozilla::UniquePtr, + pub flags: ::std::os::raw::c_uint, + pub exnType: i16, + pub _bitfield_1: u8, + pub __bindgen_padding_0: u8, + } + #[test] + fn bindgen_test_layout_JSErrorReport() { + assert_eq!(::std::mem::size_of::() , 72usize , concat ! + ( "Size of: " , stringify ! ( JSErrorReport ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat + ! ( "Alignment of " , stringify ! ( JSErrorReport ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . linebuf_ as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( linebuf_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . linebufLength_ as + * const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( linebufLength_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . tokenOffset_ as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( tokenOffset_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . notes as * const + _ as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( notes ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . flags as * const + _ as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const JSErrorReport ) ) . exnType as * + const _ as usize } , 68usize , concat ! ( + "Alignment of field: " , stringify ! ( JSErrorReport ) , + "::" , stringify ! ( exnType ) )); + } + impl JSErrorReport { + #[inline] + pub fn isMuted(&self) -> bool { + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 1u64 as u8; + let val = (unit_field_val & mask) >> 0usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_isMuted(&mut self, val: bool) { + let mask = 1u64 as u8; + let val = val as u8 as u8; + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 0usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] + pub fn ownsLinebuf_(&self) -> bool { + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 2u64 as u8; + let val = (unit_field_val & mask) >> 1usize; + unsafe { ::std::mem::transmute(val as u8) } + } + #[inline] + pub fn set_ownsLinebuf_(&mut self, val: bool) { + let mask = 2u64 as u8; + let val = val as u8 as u8; + let mut unit_field_val: u8 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as *mut u8 + as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 1usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] + pub fn new_bitfield_1(isMuted: bool, ownsLinebuf_: bool) -> u8 { + ({ ({ 0 } | ((isMuted as u8 as u8) << 0usize) & (1u64 as u8)) } | + ((ownsLinebuf_ as u8 as u8) << 1usize) & (2u64 as u8)) + } + } /// Factors implementation for all template versions of nsCOMPtr. /// /// Here's the way people normally do things like this: @@ -12124,7 +12195,7 @@ pub mod root { #[derive(Debug)] pub struct gfxFontFeatureValueSet_ValueList { pub name: ::nsstring::nsStringRepr, - pub featureSelectors: root::nsTArray<::std::os::raw::c_uint>, + pub featureSelectors: root::nsTArray, } #[test] fn bindgen_test_layout_gfxFontFeatureValueSet_ValueList() { @@ -12229,7 +12300,7 @@ pub mod root { pub struct gfxFontFeatureValueSet_FeatureValueHashEntry { pub _base: root::PLDHashEntryHdr, pub mKey: root::gfxFontFeatureValueSet_FeatureValueHashKey, - pub mValues: root::nsTArray<::std::os::raw::c_uint>, + pub mValues: root::nsTArray, } pub type gfxFontFeatureValueSet_FeatureValueHashEntry_KeyType = *const root::gfxFontFeatureValueSet_FeatureValueHashKey; @@ -12327,7 +12398,7 @@ pub mod root { pub alternateValues: root::nsTArray, pub featureValueLookup: root::RefPtr, pub fontFeatureSettings: root::nsTArray, - pub fontVariationSettings: root::nsTArray, + pub fontVariationSettings: root::nsTArray, pub languageOverride: u32, } #[test] @@ -15285,7 +15356,7 @@ pub mod root { /// tracking. NOTE: A string buffer can be modified only if its reference /// count is 1. #[repr(C)] - #[derive(Debug, Copy)] + #[derive(Debug)] pub struct nsStringBuffer { pub mRefCount: u32, pub mStorageSize: u32, @@ -15307,9 +15378,6 @@ pub mod root { "Alignment of field: " , stringify ! ( nsStringBuffer ) , "::" , stringify ! ( mStorageSize ) )); } - impl Clone for nsStringBuffer { - fn clone(&self) -> Self { *self } - } #[repr(C)] #[derive(Debug, Copy)] pub struct nsIAtom { @@ -15326,6 +15394,13 @@ pub mod root { pub struct nsIAtom_COMTypeInfo { pub _address: u8, } + #[repr(u8)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub enum nsIAtom_AtomKind { + DynamicAtom = 0, + StaticAtom = 1, + HTML5Atom = 2, + } #[test] fn bindgen_test_layout_nsIAtom() { assert_eq!(::std::mem::size_of::() , 24usize , concat ! ( @@ -15358,13 +15433,13 @@ pub mod root { *mut u32 as *mut u8, ::std::mem::size_of::()) }; - let mask = 2147483647u64 as u32; + let mask = 1073741823u64 as u32; let val = (unit_field_val & mask) >> 0usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] pub fn set_mLength(&mut self, val: u32) { - let mask = 2147483647u64 as u32; + let mask = 1073741823u64 as u32; let val = val as u32 as u32; let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; @@ -15386,7 +15461,7 @@ pub mod root { } } #[inline] - pub fn mIsStatic(&self) -> u32 { + pub fn mKind(&self) -> u32 { let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -15396,13 +15471,13 @@ pub mod root { *mut u32 as *mut u8, ::std::mem::size_of::()) }; - let mask = 2147483648u64 as u32; - let val = (unit_field_val & mask) >> 31usize; + let mask = 3221225472u64 as u32; + let val = (unit_field_val & mask) >> 30usize; unsafe { ::std::mem::transmute(val as u32) } } #[inline] - pub fn set_mIsStatic(&mut self, val: u32) { - let mask = 2147483648u64 as u32; + pub fn set_mKind(&mut self, val: u32) { + let mask = 3221225472u64 as u32; let val = val as u32 as u32; let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() }; @@ -15414,7 +15489,7 @@ pub mod root { ::std::mem::size_of::()) }; unit_field_val &= !mask; - unit_field_val |= (val << 31usize) & mask; + unit_field_val |= (val << 30usize) & mask; unsafe { ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as *const u8, @@ -15424,14 +15499,12 @@ pub mod root { } } #[inline] - pub fn new_bitfield_1(mLength: u32, mIsStatic: u32) -> u32 { + pub fn new_bitfield_1(mLength: u32, mKind: u32) -> u32 { ({ ({ 0 } | ((mLength as u32 as u32) << 0usize) & - (2147483647u64 as u32)) - } | - ((mIsStatic as u32 as u32) << 31usize) & - (2147483648u64 as u32)) + (1073741823u64 as u32)) + } | ((mKind as u32 as u32) << 30usize) & (3221225472u64 as u32)) } } #[repr(C)] @@ -15595,6 +15668,9 @@ pub mod root { pub const nsIRequest_LOAD_HTML_OBJECT_DATA: root::nsIRequest__bindgen_ty_1 = nsIRequest__bindgen_ty_1::LOAD_HTML_OBJECT_DATA; + pub const nsIRequest_LOAD_DOCUMENT_NEEDS_COOKIE: + root::nsIRequest__bindgen_ty_1 = + nsIRequest__bindgen_ty_1::LOAD_DOCUMENT_NEEDS_COOKIE; pub const nsIRequest_INHIBIT_CACHING: root::nsIRequest__bindgen_ty_1 = nsIRequest__bindgen_ty_1::INHIBIT_CACHING; pub const nsIRequest_INHIBIT_PERSISTENT_CACHING: @@ -15623,6 +15699,7 @@ pub mod root { LOAD_NORMAL = 0, LOAD_BACKGROUND = 1, LOAD_HTML_OBJECT_DATA = 2, + LOAD_DOCUMENT_NEEDS_COOKIE = 4, INHIBIT_CACHING = 128, INHIBIT_PERSISTENT_CACHING = 256, LOAD_BYPASS_CACHE = 512, @@ -16664,7 +16741,7 @@ pub mod root { pub mUpgradeInsecurePreloads: bool, pub mHSTSPrimingURIList: [u64; 5usize], pub mDocumentContainer: u64, - pub mCharacterSet: root::mozilla::NotNull<*const root::mozilla::Encoding>, + pub mCharacterSet: root::mozilla::NotNull<*const root::nsIDocument_Encoding>, pub mCharacterSetSource: i32, pub mParentDocument: *mut root::nsIDocument, pub mCachedRootElement: *mut root::mozilla::dom::Element, @@ -16713,7 +16790,7 @@ pub mod root { /// The current frame request callback handle pub mFrameRequestCallbackCounter: i32, pub mStaticCloneCount: u32, - pub mBlockedTrackingNodes: root::nsTArray, + pub mBlockedTrackingNodes: root::nsTArray, pub mWindow: *mut root::nsPIDOMWindowInner, pub mCachedEncoder: root::nsCOMPtr, pub mFrameRequestCallbacks: root::nsTArray, @@ -18821,7 +18898,7 @@ pub mod root { } } #[inline] - pub fn mIsScopedStyleEnabled(&self) -> ::std::os::raw::c_uint { + pub fn mMightHaveStaleServoData(&self) -> bool { let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -18831,15 +18908,14 @@ pub mod root { *mut u64 as *mut u8, ::std::mem::size_of::()) }; - let mask = 422212465065984u64 as u64; + let mask = 140737488355328u64 as u64; let val = (unit_field_val & mask) >> 47usize; - unsafe { ::std::mem::transmute(val as u32) } + unsafe { ::std::mem::transmute(val as u8) } } #[inline] - pub fn set_mIsScopedStyleEnabled(&mut self, - val: ::std::os::raw::c_uint) { - let mask = 422212465065984u64 as u64; - let val = val as u32 as u64; + pub fn set_mMightHaveStaleServoData(&mut self, val: bool) { + let mask = 140737488355328u64 as u64; + let val = val as u8 as u64; let mut unit_field_val: u64 = unsafe { ::std::mem::uninitialized() }; unsafe { @@ -18860,6 +18936,45 @@ pub mod root { } } #[inline] + pub fn mIsScopedStyleEnabled(&self) -> ::std::os::raw::c_uint { + let mut unit_field_val: u64 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as + *mut u64 as *mut u8, + ::std::mem::size_of::()) + }; + let mask = 844424930131968u64 as u64; + let val = (unit_field_val & mask) >> 48usize; + unsafe { ::std::mem::transmute(val as u32) } + } + #[inline] + pub fn set_mIsScopedStyleEnabled(&mut self, + val: ::std::os::raw::c_uint) { + let mask = 844424930131968u64 as u64; + let val = val as u32 as u64; + let mut unit_field_val: u64 = + unsafe { ::std::mem::uninitialized() }; + unsafe { + ::std::ptr::copy_nonoverlapping(&self._bitfield_1 as *const _ + as *const u8, + &mut unit_field_val as + *mut u64 as *mut u8, + ::std::mem::size_of::()) + }; + unit_field_val &= !mask; + unit_field_val |= (val << 48usize) & mask; + unsafe { + ::std::ptr::copy_nonoverlapping(&unit_field_val as *const _ as + *const u8, + &mut self._bitfield_1 as + *mut _ as *mut u8, + ::std::mem::size_of::()); + } + } + #[inline] pub fn new_bitfield_1(mBidiEnabled: bool, mMathMLEnabled: bool, mIsInitialDocumentInWindow: bool, mIgnoreDocGroupMismatches: bool, @@ -18902,6 +19017,7 @@ pub mod root { mFrameRequestCallbacksScheduled: bool, mIsTopLevelContentDocument: bool, mIsContentDocument: bool, + mMightHaveStaleServoData: bool, mIsScopedStyleEnabled: ::std::os::raw::c_uint) -> u64 { ({ @@ -18952,542 +19068,555 @@ pub mod root { ({ ({ ({ - 0 + ({ + 0 + } + | + ((mBidiEnabled + as + u8 + as + u64) + << + 0usize) + & + (1u64 + as + u64)) } | - ((mBidiEnabled + ((mMathMLEnabled as u8 as u64) << - 0usize) + 1usize) & - (1u64 + (2u64 as u64)) } | - ((mMathMLEnabled + ((mIsInitialDocumentInWindow as u8 as u64) << - 1usize) + 2usize) & - (2u64 + (4u64 as u64)) } | - ((mIsInitialDocumentInWindow + ((mIgnoreDocGroupMismatches as u8 as u64) << - 2usize) + 3usize) & - (4u64 + (8u64 as u64)) } | - ((mIgnoreDocGroupMismatches + ((mLoadedAsData as u8 as u64) << - 3usize) + 4usize) & - (8u64 + (16u64 as u64)) } | - ((mLoadedAsData + ((mLoadedAsInteractiveData as u8 as u64) << - 4usize) + 5usize) & - (16u64 + (32u64 as u64)) } | - ((mLoadedAsInteractiveData + ((mMayStartLayout as u8 as u64) << - 5usize) + 6usize) & - (32u64 + (64u64 as u64)) } | - ((mMayStartLayout + ((mHaveFiredTitleChange as u8 as u64) << - 6usize) + 7usize) & - (64u64 + (128u64 as u64)) } | - ((mHaveFiredTitleChange + ((mIsShowing as u8 as u64) << - 7usize) + 8usize) & - (128u64 + (256u64 as u64)) } | - ((mIsShowing + ((mVisible as u8 as u64) << - 8usize) + 9usize) & - (256u64 + (512u64 as u64)) } | - ((mVisible + ((mHasReferrerPolicyCSP as u8 as u64) << - 9usize) + 10usize) & - (512u64 + (1024u64 as u64)) } | - ((mHasReferrerPolicyCSP + ((mRemovedFromDocShell as u8 as u64) << - 10usize) + 11usize) & - (1024u64 + (2048u64 as u64)) } | - ((mRemovedFromDocShell + ((mAllowDNSPrefetch as u8 as u64) << - 11usize) + 12usize) & - (2048u64 + (4096u64 as u64)) } | - ((mAllowDNSPrefetch + ((mIsStaticDocument as u8 as u64) << - 12usize) + 13usize) & - (4096u64 + (8192u64 as u64)) } | - ((mIsStaticDocument + ((mCreatingStaticClone as u8 as u64) << - 13usize) + 14usize) & - (8192u64 + (16384u64 as u64)) } | - ((mCreatingStaticClone + ((mInUnlinkOrDeletion as u8 as u64) << - 14usize) + 15usize) & - (16384u64 + (32768u64 as u64)) } | - ((mInUnlinkOrDeletion + ((mHasHadScriptHandlingObject as u8 as u64) << - 15usize) + 16usize) & - (32768u64 + (65536u64 as u64)) } | - ((mHasHadScriptHandlingObject + ((mIsBeingUsedAsImage as u8 as u64) << - 16usize) + 17usize) & - (65536u64 + (131072u64 as u64)) } | - ((mIsBeingUsedAsImage + ((mIsSyntheticDocument as u8 as u64) << - 17usize) + 18usize) & - (131072u64 + (262144u64 as u64)) } | - ((mIsSyntheticDocument + ((mHasLinksToUpdate as u8 as u64) << - 18usize) + 19usize) & - (262144u64 + (524288u64 as u64)) } | - ((mHasLinksToUpdate + ((mHasLinksToUpdateRunnable as u8 as u64) << - 19usize) + 20usize) & - (524288u64 + (1048576u64 as u64)) } | - ((mHasLinksToUpdateRunnable + ((mMayHaveDOMMutationObservers as u8 as u64) << - 20usize) + 21usize) & - (1048576u64 + (2097152u64 as u64)) } | - ((mMayHaveDOMMutationObservers + ((mMayHaveAnimationObservers as u8 as u64) << - 21usize) + 22usize) & - (2097152u64 + (4194304u64 as u64)) } | - ((mMayHaveAnimationObservers + ((mHasMixedActiveContentLoaded as u8 as u64) << - 22usize) + 23usize) & - (4194304u64 + (8388608u64 as u64)) } | - ((mHasMixedActiveContentLoaded + ((mHasMixedActiveContentBlocked as u8 as u64) << - 23usize) + 24usize) & - (8388608u64 + (16777216u64 as u64)) } | - ((mHasMixedActiveContentBlocked + ((mHasMixedDisplayContentLoaded as u8 as u64) << - 24usize) + 25usize) & - (16777216u64 + (33554432u64 as u64)) } | - ((mHasMixedDisplayContentLoaded + ((mHasMixedDisplayContentBlocked as u8 as u64) << - 25usize) + 26usize) & - (33554432u64 + (67108864u64 as u64)) } | - ((mHasMixedDisplayContentBlocked + ((mHasMixedContentObjectSubrequest as u8 as u64) << - 26usize) + 27usize) & - (67108864u64 + (134217728u64 as u64)) } | - ((mHasMixedContentObjectSubrequest + ((mHasCSP as u8 as u64) << - 27usize) + 28usize) & - (134217728u64 + (268435456u64 as u64)) } | - ((mHasCSP + ((mHasUnsafeEvalCSP as u8 as u64) << - 28usize) + 29usize) & - (268435456u64 + (536870912u64 as u64)) } | - ((mHasUnsafeEvalCSP + ((mHasUnsafeInlineCSP as u8 as u64) << - 29usize) + 30usize) & - (536870912u64 + (1073741824u64 as u64)) } | - ((mHasUnsafeInlineCSP + ((mHasTrackingContentBlocked as u8 as u64) << - 30usize) + 31usize) & - (1073741824u64 + (2147483648u64 as u64)) } | - ((mHasTrackingContentBlocked + ((mHasTrackingContentLoaded as u8 as u64) << - 31usize) + 32usize) & - (2147483648u64 + (4294967296u64 as u64)) } | - ((mHasTrackingContentLoaded + ((mBFCacheDisallowed as u8 as u64) << - 32usize) + 33usize) & - (4294967296u64 + (8589934592u64 as u64)) } | - ((mBFCacheDisallowed + ((mHasHadDefaultView as u8 as u64) << - 33usize) + 34usize) & - (8589934592u64 + (17179869184u64 as u64)) } | - ((mHasHadDefaultView + ((mStyleSheetChangeEventsEnabled as u8 as u64) << - 34usize) + 35usize) & - (17179869184u64 + (34359738368u64 as u64)) } | - ((mStyleSheetChangeEventsEnabled + ((mIsSrcdocDocument as u8 as u64) << - 35usize) + 36usize) & - (34359738368u64 + (68719476736u64 as u64)) } | - ((mIsSrcdocDocument + ((mDidDocumentOpen as u8 as u64) << - 36usize) + 37usize) & - (68719476736u64 + (137438953472u64 as u64)) } | - ((mDidDocumentOpen + ((mHasDisplayDocument as u8 as u64) << - 37usize) + 38usize) & - (137438953472u64 + (274877906944u64 as u64)) } | - ((mHasDisplayDocument + ((mFontFaceSetDirty as u8 as u64) << - 38usize) & - (274877906944u64 + 39usize) & + (549755813888u64 as u64)) } | - ((mFontFaceSetDirty + ((mGetUserFontSetCalled as u8 as u64) - << 39usize) & - (549755813888u64 + << 40usize) & + (1099511627776u64 as u64)) } | - ((mGetUserFontSetCalled as - u8 as u64) << - 40usize) & - (1099511627776u64 as + ((mPostedFlushUserFontSet + as u8 as u64) << + 41usize) & + (2199023255552u64 as u64)) } | - ((mPostedFlushUserFontSet as u8 - as u64) << 41usize) & - (2199023255552u64 as u64)) + ((mDidFireDOMContentLoaded as + u8 as u64) << 42usize) & + (4398046511104u64 as u64)) } | - ((mDidFireDOMContentLoaded as u8 as - u64) << 42usize) & - (4398046511104u64 as u64)) + ((mHasScrollLinkedEffect as u8 as + u64) << 43usize) & + (8796093022208u64 as u64)) } | - ((mHasScrollLinkedEffect as u8 as u64) << - 43usize) & - (8796093022208u64 as u64)) + ((mFrameRequestCallbacksScheduled as u8 + as u64) << 44usize) & + (17592186044416u64 as u64)) } | - ((mFrameRequestCallbacksScheduled as u8 as - u64) << 44usize) & - (17592186044416u64 as u64)) + ((mIsTopLevelContentDocument as u8 as u64) << + 45usize) & (35184372088832u64 as u64)) } | - ((mIsTopLevelContentDocument as u8 as u64) << - 45usize) & (35184372088832u64 as u64)) + ((mIsContentDocument as u8 as u64) << 46usize) & + (70368744177664u64 as u64)) } | - ((mIsContentDocument as u8 as u64) << 46usize) & - (70368744177664u64 as u64)) + ((mMightHaveStaleServoData as u8 as u64) << 47usize) & + (140737488355328u64 as u64)) } | - ((mIsScopedStyleEnabled as u32 as u64) << 47usize) & - (422212465065984u64 as u64)) + ((mIsScopedStyleEnabled as u32 as u64) << 48usize) & + (844424930131968u64 as u64)) } } #[repr(C)] @@ -19501,7 +19630,7 @@ pub mod root { pub _base: root::nsStubMutationObserver, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub mBoundContentSet: u64, - pub mWrapperTable: u64, + pub mWrapperTable: root::nsAutoPtr, pub mDocumentTable: u64, pub mLoadingDocTable: u64, pub mAttachedStack: root::nsBindingList, @@ -19782,7 +19911,6 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct nsStyleContext { - pub mParent: root::RefPtr, pub mPseudoTag: root::nsCOMPtr, pub mBits: u64, } @@ -19796,23 +19924,18 @@ pub mod root { } #[test] fn bindgen_test_layout_nsStyleContext() { - assert_eq!(::std::mem::size_of::() , 24usize , concat + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( "Size of: " , stringify ! ( nsStyleContext ) )); assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsStyleContext ) )); - assert_eq! (unsafe { - & ( * ( 0 as * const nsStyleContext ) ) . mParent as * - const _ as usize } , 0usize , concat ! ( - "Alignment of field: " , stringify ! ( nsStyleContext ) , - "::" , stringify ! ( mParent ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleContext ) ) . mPseudoTag as * - const _ as usize } , 8usize , concat ! ( + const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleContext ) , "::" , stringify ! ( mPseudoTag ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleContext ) ) . mBits as * const - _ as usize } , 16usize , concat ! ( + _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleContext ) , "::" , stringify ! ( mBits ) )); } @@ -24548,57 +24671,57 @@ pub mod root { pub struct nsRange { _unused: [u8; 0], } - pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_LISTENERMANAGER; - pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_PROPERTIES; - pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_ANONYMOUS_ROOT; - pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; - pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_NATIVE_ANONYMOUS_ROOT; - pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_FORCE_XBL_BINDINGS; - pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_MAY_BE_IN_BINDING_MNGR; - pub const NODE_IS_EDITABLE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_EDITABLE; - pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_NATIVE_ANONYMOUS; - pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_IN_SHADOW_TREE; - pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_EMPTY_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_SLOW_SELECTOR; - pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_EDGE_CHILD_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; - pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_ALL_SELECTOR_FLAGS; - pub const NODE_NEEDS_FRAME: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_NEEDS_FRAME; - pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_DESCENDANTS_NEED_FRAMES; - pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_ACCESSKEY; - pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_DIRECTION_RTL; - pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_HAS_DIRECTION_LTR; - pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_ALL_DIRECTION_FLAGS; - pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_CHROME_ONLY_ACCESS; - pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; - pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_18 = - _bindgen_ty_18::NODE_TYPE_SPECIFIC_BITS_OFFSET; + pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_LISTENERMANAGER; + pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_PROPERTIES; + pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_ANONYMOUS_ROOT; + pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; + pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS_ROOT; + pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_FORCE_XBL_BINDINGS; + pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_MAY_BE_IN_BINDING_MNGR; + pub const NODE_IS_EDITABLE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_EDITABLE; + pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS; + pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_IN_SHADOW_TREE; + pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_EMPTY_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR; + pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_EDGE_CHILD_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; + pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_ALL_SELECTOR_FLAGS; + pub const NODE_NEEDS_FRAME: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_NEEDS_FRAME; + pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_DESCENDANTS_NEED_FRAMES; + pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_ACCESSKEY; + pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_DIRECTION_RTL; + pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_HAS_DIRECTION_LTR; + pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_ALL_DIRECTION_FLAGS; + pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_CHROME_ONLY_ACCESS; + pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; + pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_77 = + _bindgen_ty_77::NODE_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_18 { + pub enum _bindgen_ty_77 { NODE_HAS_LISTENERMANAGER = 4, NODE_HAS_PROPERTIES = 8, NODE_IS_ANONYMOUS_ROOT = 16, @@ -28287,7 +28410,7 @@ pub mod root { pub _base_4: root::nsITimedChannel, pub mRefCnt: root::nsAutoRefCnt, pub mBehaviour: root::mozilla::UniquePtr, - pub mURI: root::RefPtr, + pub mURI: root::RefPtr, pub mListener: *mut root::imgINotificationObserver, pub mLoadGroup: root::nsCOMPtr, pub mTabGroup: root::RefPtr, @@ -29272,9 +29395,6 @@ pub mod root { "Alignment of field: " , stringify ! ( nsCSSValue_Array ) , "::" , stringify ! ( mArray ) )); } - #[repr(u32)] - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum nsCSSValue_Serialization { eNormalized = 0, } #[repr(C)] #[derive(Debug, Copy)] pub struct nsCSSValue__bindgen_ty_1 { @@ -31410,7 +31530,7 @@ pub mod root { pub type RawGeckoPropertyValuePairList = root::nsTArray; pub type RawGeckoComputedKeyframeValuesList = - root::nsTArray>; + root::nsTArray; pub type RawGeckoStyleAnimationList = root::nsStyleAutoArray; pub type RawGeckoFontFaceRuleList = @@ -32083,46 +32203,46 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISMILAttr ) )); } - pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; pub const ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO: - root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_20 + root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_79 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_3; + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; pub const ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT: - root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; - pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_PENDING_RESTYLE_FLAGS; - pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; - pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_ALL_RESTYLE_FLAGS; - pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_20 = - _bindgen_ty_20::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; + root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; + pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_PENDING_RESTYLE_FLAGS; + pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; + pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_ALL_RESTYLE_FLAGS; + pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_79 = + _bindgen_ty_79::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_20 { + pub enum _bindgen_ty_79 { ELEMENT_SHARED_RESTYLE_BIT_1 = 8388608, ELEMENT_SHARED_RESTYLE_BIT_2 = 16777216, ELEMENT_SHARED_RESTYLE_BIT_3 = 33554432, @@ -32719,7 +32839,7 @@ pub mod root { "::" , stringify ! ( mArray ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char16_t_close0_instantiation() { + fn __bindgen_test_layout_nsCharTraits_open0_nsStringRepr_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -32730,62 +32850,33 @@ pub mod root { root::nsCharTraits ) )); } #[test] - fn __bindgen_test_layout_nsReadingIterator_open0_char16_t_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 24usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsReadingIterator ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsReadingIterator ) )); - } - #[test] - fn __bindgen_test_layout_nsWritingIterator_open0_char16_t_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 24usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsWritingIterator ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsWritingIterator ) )); - } - #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 1usize , - concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsCharTraits ) )); - assert_eq!(::std::mem::align_of::() , 1usize , - concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsCharTraits ) )); - } - #[test] - fn __bindgen_test_layout_nsReadingIterator_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsReadingIterator_open0_nsStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 24usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsReadingIterator<::std::os::raw::c_char> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsReadingIterator + ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsReadingIterator<::std::os::raw::c_char> ) )); + root::nsReadingIterator + ) )); } #[test] - fn __bindgen_test_layout_nsWritingIterator_open0_char_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsWritingIterator_open0_nsStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 24usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsWritingIterator<::std::os::raw::c_char> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsWritingIterator + ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsWritingIterator<::std::os::raw::c_char> ) )); + root::nsWritingIterator + ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char16_t_close0_instantiation_1() { + fn __bindgen_test_layout_nsCharTraits_open0_nsCStringRepr_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -32796,7 +32887,44 @@ pub mod root { root::nsCharTraits ) )); } #[test] - fn __bindgen_test_layout_nsCharTraits_open0_char_close0_instantiation_1() { + fn __bindgen_test_layout_nsReadingIterator_open0_nsCStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 24usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsReadingIterator + ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsReadingIterator + ) )); + } + #[test] + fn __bindgen_test_layout_nsWritingIterator_open0_nsCStringRepr_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 24usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsWritingIterator + ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsWritingIterator + ) )); + } + #[test] + fn __bindgen_test_layout_nsCharTraits_open0_nsSubstringTuple_char_type_close0_instantiation() { + assert_eq!(::std::mem::size_of::() , 1usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsCharTraits ) )); + assert_eq!(::std::mem::align_of::() , 1usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsCharTraits ) )); + } + #[test] + fn __bindgen_test_layout_nsCharTraits_open0_nsCSubstringTuple_char_type_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -32897,26 +33025,26 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxFontFeatureValueSet_ValueList_close0_instantiation() { @@ -32932,26 +33060,26 @@ pub mod root { )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_2() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>() , 8usize , + concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , + concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<::std::os::raw::c_uint> ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxAlternateValue_close0_instantiation() { @@ -32987,18 +33115,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_201606_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_199574_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33266,6 +33394,17 @@ pub mod root { root::RefPtr ) )); } #[test] + fn __bindgen_test_layout_RefPtr_open0_ServoStyleContext_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::RefPtr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_1() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -33288,7 +33427,7 @@ pub mod root { root::mozilla::binding_danger::TErrorResult ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_203357_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_201334_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33449,7 +33588,7 @@ pub mod root { root::JS::DeletePolicy ) )); } #[test] - fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_208887__bindgen_ty_id_208894_close0_instantiation() { + fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_206893__bindgen_ty_id_206900_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33675,15 +33814,15 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211375_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_209367_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::nsIDocument_Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); + root::nsTArray<*mut root::nsIDocument_Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation() { @@ -33743,15 +33882,15 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211677_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_209669_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::nsIDocument_Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::mozilla::dom::Element> ) )); + root::nsTArray<*mut root::nsIDocument_Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation_1() { @@ -33855,16 +33994,16 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_212219_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_210211_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::mozilla::Encoding> ) + root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) )); - assert_eq!(::std::mem::align_of::>() + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::mozilla::Encoding> ) + root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) )); } #[test] @@ -34066,26 +34205,15 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCOMPtr_open1_nsIWeakReference_close1_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , + fn __bindgen_test_layout_nsTArray_open0_nsWeakPtr_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); - } - #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 8usize , concat ! - ( - "Size of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); - assert_eq!(::std::mem::align_of::() , 8usize , concat - ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); + root::nsTArray ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIDocumentEncoder_close0_instantiation() { @@ -34235,7 +34363,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212632_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_210621_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34325,7 +34453,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_213036_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211018_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34426,7 +34554,7 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214000_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211979_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34457,13 +34585,17 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsAutoPtr_open0_nsInterfaceHashtable_open1_nsISupportsHashKey_nsIXPConnectWrappedJS_close1_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( u64 ) + fn __bindgen_test_layout_nsAutoPtr_open0_nsBindingManager_WrapperHashtable_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsAutoPtr ) )); - assert_eq!(::std::mem::align_of::() , 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - u64 ) )); + root::nsAutoPtr ) + )); } #[test] fn __bindgen_test_layout_nsAutoPtr_open0_nsRefPtrHashtable_open1_nsURIHashKey_nsXBLDocumentInfo_close1_close0_instantiation() { @@ -34515,7 +34647,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214303_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212279_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34526,7 +34658,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214308_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212284_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34537,17 +34669,6 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_nsStyleContext_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); - } - #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIAtom_close0_instantiation_3() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( @@ -34594,7 +34715,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214785_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212759_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34970,7 +35091,7 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_Element_close0_instantiation() { + fn __bindgen_test_layout_nsCOMPtr_open0_nsDOMAttributeMap_Element_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35218,7 +35339,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation_1() { + fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35229,7 +35350,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_217614_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_215588_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35308,7 +35429,7 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_223939_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_221863_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35341,7 +35462,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_225100_close0_instantiation() { + fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_223024_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35352,7 +35473,7 @@ pub mod root { root::JS::Heap<*mut root::JSObject> ) )); } #[test] - fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_225104_close0_instantiation() { + fn __bindgen_test_layout_Heap_open0__bindgen_ty_id_223028_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35374,7 +35495,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_TenuredHeap_open0__bindgen_ty_id_225111_close0_instantiation() { + fn __bindgen_test_layout_TenuredHeap_open0__bindgen_ty_id_223035_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35453,7 +35574,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226568_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224214_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35648,7 +35769,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227943_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_225662_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35753,7 +35874,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230331_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228044_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35898,15 +36019,15 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_ImageURL_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_RefPtr_open0_imgRequestProxy_ImageURL_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); + root::RefPtr ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsILoadGroup_close0_instantiation() { @@ -36454,7 +36575,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_232810_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230515_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36691,7 +36812,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240615_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238214_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36702,7 +36823,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240620_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238219_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36790,7 +36911,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240733_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238332_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37077,7 +37198,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242339_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_239917_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37099,7 +37220,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242497_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240073_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37110,7 +37231,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242502_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240078_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37132,6 +37253,17 @@ pub mod root { root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_17() { + assert_eq!(::std::mem::size_of::>() , + 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTArray<::nsstring::nsStringRepr> ) )); + assert_eq!(::std::mem::align_of::>() , + 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTArray<::nsstring::nsStringRepr> ) )); + } + #[test] fn __bindgen_test_layout_RefPtr_open0_RawServoMediaList_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -37176,18 +37308,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_244545_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242138_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37198,7 +37330,7 @@ pub mod root { root::nsTArray<*mut root::mozilla::css::DocumentRule> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_244551_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242144_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( diff --git a/servo/components/style/gecko_string_cache/mod.rs b/servo/components/style/gecko_string_cache/mod.rs index f3bb04f6c55d..aa3c3b731eab 100644 --- a/servo/components/style/gecko_string_cache/mod.rs +++ b/servo/components/style/gecko_string_cache/mod.rs @@ -10,7 +10,7 @@ use gecko_bindings::bindings::Gecko_AddRefAtom; use gecko_bindings::bindings::Gecko_Atomize; use gecko_bindings::bindings::Gecko_Atomize16; use gecko_bindings::bindings::Gecko_ReleaseAtom; -use gecko_bindings::structs::nsIAtom; +use gecko_bindings::structs::{nsIAtom, nsIAtom_AtomKind}; use nsstring::{nsAString, nsString}; use precomputed_hash::PrecomputedHash; use std::ascii::AsciiExt; @@ -149,7 +149,7 @@ impl WeakAtom { #[inline] pub fn is_static(&self) -> bool { unsafe { - (*self.as_ptr()).mIsStatic() != 0 + (*self.as_ptr()).mKind() == nsIAtom_AtomKind::StaticAtom as u32 } } From a7d696a18f0585a4f0af12e1a77a9f8e61455d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 14:18:15 +0200 Subject: [PATCH 002/166] Bug 1362338: Preliminary whitespace cleanup in nsIAtom.idl. r=froydnj MozReview-Commit-ID: DN2tN0OMWEk --- xpcom/ds/nsIAtom.idl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index f1085089bbc1..37555d2c23d2 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -17,16 +17,16 @@ native MallocSizeOf(mozilla::MallocSizeOf); * could be dangerous since double-wrapping could lead to loss of * pointer identity. */ - + [scriptable, builtinclass, uuid(8b8c11d4-3ed5-4079-8974-73c7576cdb34)] interface nsIAtom : nsISupports { /** * Get the Unicode or UTF8 value for the string */ - [binaryname(ScriptableToString)] AString toString(); + [binaryname(ScriptableToString)] AString toString(); [noscript] AUTF8String toUTF8String(); - + /** * Compare the atom to a specific string value * Note that this will NEVER return/throw an error condition. @@ -137,7 +137,7 @@ extern already_AddRefed NS_AtomizeMainThread(const nsAString& aUTF16Str extern nsrefcnt NS_GetNumberOfAtoms(void); /** - * Return a pointer for a static atom for the string or null if there's + * Return a pointer for a static atom for the string or null if there's * no static atom for this string. */ extern nsIAtom* NS_GetStaticAtom(const nsAString& aUTF16String); From e99fdbe52e8dab680c7894a0d3106692b143e179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 14:19:30 +0200 Subject: [PATCH 003/166] Bug 1362338: Take a bit from the atom's length to store a tristate. r=froydnj MozReview-Commit-ID: Elu9EioSDXk --- parser/html/nsHtml5Atom.cpp | 2 +- xpcom/ds/nsAtomTable.cpp | 4 ++-- xpcom/ds/nsIAtom.idl | 31 ++++++++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/parser/html/nsHtml5Atom.cpp b/parser/html/nsHtml5Atom.cpp index 4d15c5e41d5f..120cfb85def5 100644 --- a/parser/html/nsHtml5Atom.cpp +++ b/parser/html/nsHtml5Atom.cpp @@ -9,7 +9,7 @@ nsHtml5Atom::nsHtml5Atom(const nsAString& aString) { mLength = aString.Length(); - mIsStatic = false; + SetKind(AtomKind::HTML5Atom); RefPtr buf = nsStringBuffer::FromString(aString); if (buf) { mString = static_cast(buf->Data()); diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 0c51441e9d53..634855f80170 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -93,7 +93,7 @@ private: : mRefCnt(1) { mLength = aString.Length(); - mIsStatic = false; + SetKind(AtomKind::DynamicAtom); RefPtr buf = nsStringBuffer::FromString(aString); if (buf) { mString = static_cast(buf->Data()); @@ -171,7 +171,7 @@ public: StaticAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash) { mLength = aLength; - mIsStatic = true; + SetKind(AtomKind::StaticAtom); mString = static_cast(aStringBuffer->Data()); #if defined(NS_BUILD_REFCNT_LOGGING) diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index 37555d2c23d2..60cddbee051e 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -37,6 +37,14 @@ interface nsIAtom : nsISupports size_t SizeOfIncludingThis(in MallocSizeOf aMallocSizeOf); %{C++ + // The kind of atom we have, in order to be able to devirtualize hot stuff + // looking at mKind. + enum class AtomKind : uint8_t { + DynamicAtom = 0, + StaticAtom = 1, + HTML5Atom = 2, + }; + // note these are NOT virtual so they won't muck with the vtable! inline bool Equals(char16ptr_t aString, uint32_t aLength) const { @@ -48,8 +56,25 @@ interface nsIAtom : nsISupports return Equals(aString.BeginReading(), aString.Length()); } + inline void SetKind(AtomKind aKind) { + mKind = static_cast(aKind); + MOZ_ASSERT(Kind() == aKind); + } + + inline AtomKind Kind() const { + return static_cast(mKind); + } + + inline bool IsDynamicAtom() const { + return Kind() == AtomKind::DynamicAtom; + } + + inline bool IsHTML5Atom() const { + return Kind() == AtomKind::HTML5Atom; + } + inline bool IsStaticAtom() const { - return mIsStatic; + return Kind() == AtomKind::StaticAtom; } inline char16ptr_t GetUTF16String() const { @@ -80,8 +105,8 @@ interface nsIAtom : nsISupports } protected: - uint32_t mLength:31; - uint32_t mIsStatic:1; + uint32_t mLength: 30; + uint32_t mKind: 2; // nsIAtom::AtomKind uint32_t mHash; /** * WARNING! There is an invisible constraint on |mString|: the chars it From 300ebe9ee1d399ecdf3ea7ca18c0bde1ff830269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 14:20:17 +0200 Subject: [PATCH 004/166] Bug 1362338: Make nsIAtom::AddRef and nsIAtom::Release final. r=froydnj MozReview-Commit-ID: CFWcSNocGIm --- parser/html/nsHtml5Atom.cpp | 16 +--------- parser/html/nsHtml5Atom.h | 2 +- xpcom/ds/nsAtomTable.cpp | 58 +++++++++++++++++++++++++------------ xpcom/ds/nsIAtom.idl | 3 ++ 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/parser/html/nsHtml5Atom.cpp b/parser/html/nsHtml5Atom.cpp index 120cfb85def5..343a69b3d232 100644 --- a/parser/html/nsHtml5Atom.cpp +++ b/parser/html/nsHtml5Atom.cpp @@ -40,20 +40,6 @@ nsHtml5Atom::~nsHtml5Atom() nsStringBuffer::FromData(mString)->Release(); } -NS_IMETHODIMP_(MozExternalRefCountType) -nsHtml5Atom::AddRef() -{ - NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom."); - return 2; -} - -NS_IMETHODIMP_(MozExternalRefCountType) -nsHtml5Atom::Release() -{ - NS_NOTREACHED("Attempt to Release an nsHtml5Atom."); - return 1; -} - NS_IMETHODIMP nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr) { @@ -61,7 +47,7 @@ nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_ERROR_UNEXPECTED; } -NS_IMETHODIMP +NS_IMETHODIMP nsHtml5Atom::ScriptableToString(nsAString& aBuf) { NS_NOTREACHED("Should not call ScriptableToString."); diff --git a/parser/html/nsHtml5Atom.h b/parser/html/nsHtml5Atom.h index c11fb0bade58..be56b5ed6bab 100644 --- a/parser/html/nsHtml5Atom.h +++ b/parser/html/nsHtml5Atom.h @@ -18,7 +18,7 @@ class nsHtml5Atom final : public nsIAtom { public: - NS_DECL_ISUPPORTS + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; NS_DECL_NSIATOM explicit nsHtml5Atom(const nsAString& aString); diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 634855f80170..0bb2d7ab6451 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -128,8 +128,16 @@ private: ~DynamicAtom(); public: - NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIATOM + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; + typedef mozilla::TrueType HasThreadSafeRefCnt; + + MozExternalRefCountType DoAddRef(); + MozExternalRefCountType DoRelease(); + +protected: + ThreadSafeAutoRefCnt mRefCnt; + NS_DECL_OWNINGTHREAD }; #if defined(NS_BUILD_REFCNT_LOGGING) @@ -199,23 +207,11 @@ public: // StaticAtom* pointer (in AtomTableClearEntry()), not an nsIAtom* pointer. ~StaticAtom() {} - NS_DECL_ISUPPORTS + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; NS_DECL_NSIATOM }; -NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom) - -NS_IMETHODIMP_(MozExternalRefCountType) -StaticAtom::AddRef() -{ - return 2; -} - -NS_IMETHODIMP_(MozExternalRefCountType) -StaticAtom::Release() -{ - return 1; -} +NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom); NS_IMETHODIMP DynamicAtom::ScriptableToString(nsAString& aBuf) @@ -279,6 +275,30 @@ StaticAtom::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) //---------------------------------------------------------------------- +MozExternalRefCountType +nsIAtom::AddRef() +{ + MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an nsHtml5Atom"); + if (!IsDynamicAtom()) { + MOZ_ASSERT(IsStaticAtom()); + return 2; + } + return static_cast(this)->DoAddRef(); +} + +MozExternalRefCountType +nsIAtom::Release() +{ + MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an nsHtml5Atom"); + if (!IsDynamicAtom()) { + MOZ_ASSERT(IsStaticAtom()); + return 1; + } + return static_cast(this)->DoRelease(); +} + +//---------------------------------------------------------------------- + /** * The shared hash table for atom lookups. * @@ -484,8 +504,8 @@ DynamicAtom::GCAtomTableLocked(const MutexAutoLock& aProofOfLock, NS_IMPL_QUERY_INTERFACE(DynamicAtom, nsIAtom) -NS_IMETHODIMP_(MozExternalRefCountType) -DynamicAtom::AddRef(void) +MozExternalRefCountType +DynamicAtom::DoAddRef() { nsrefcnt count = ++mRefCnt; if (count == 1) { @@ -502,8 +522,8 @@ static const uint32_t kAtomGCThreshold = 20; static const uint32_t kAtomGCThreshold = 10000; #endif -NS_IMETHODIMP_(MozExternalRefCountType) -DynamicAtom::Release(void) +MozExternalRefCountType +DynamicAtom::DoRelease() { MOZ_ASSERT(mRefCnt > 0); nsrefcnt count = --mRefCnt; diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index 60cddbee051e..0df64bfae49b 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -95,6 +95,9 @@ interface nsIAtom : nsISupports return nsStringBuffer::FromData(mString); } + MozExternalRefCountType AddRef() final; + MozExternalRefCountType Release() final; + /** * A hashcode that is better distributed than the actual atom * pointer, for use in situations that need a well-distributed From 77b71da58c27f39b1a781ce0e74ff077c5d0212a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 26 Jul 2017 15:14:07 +0200 Subject: [PATCH 005/166] Bug 1336978 - Add support of lld by adding a configure option --enable-linker='bfd', 'gold', 'lld', 'other' r=glandium MozReview-Commit-ID: 7LI2lMXO2lG --HG-- extra : rebase_source : d8531917f81e8f6e313b362ae182540312a5c676 --- build/moz.configure/toolchain.configure | 39 ++++++++++++++++++++----- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index 638180c50f11..eba0fbf65538 100755 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -1141,13 +1141,13 @@ option('--enable-gold', help='Enable GNU Gold Linker when it is not already the default', when=build_not_win_mac) +imply_option('--enable-linker', + depends_if('--enable-gold', when=build_not_win_mac)(lambda x: 'gold'), + when=build_not_win_mac) -@depends('--enable-gold', c_compiler, developer_options, check_build_environment, when=build_not_win_mac) -@checking('for ld', lambda x: x.KIND) @imports('os') @imports('shutil') -def enable_gold(enable_gold_option, c_compiler, developer_options, build_env): - linker = None +def enable_gnu_linker(enable_gold_option, c_compiler, developer_options, build_env, linker_name): # Used to check the kind of linker version_check = ['-Wl,--version'] cmd_base = c_compiler.wrapper + [c_compiler.compiler] + c_compiler.flags @@ -1182,7 +1182,7 @@ def enable_gold(enable_gold_option, c_compiler, developer_options, build_env): # The -B trick didn't work, removing the directory shutil.rmtree(targetDir) - if enable_gold_option or developer_options: + if (enable_gold_option or developer_options) and linker_name != 'bfd': result = resolve_gold() if result: @@ -1213,5 +1213,30 @@ def enable_gold(enable_gold_option, c_compiler, developer_options, build_env): KIND='other' ) -set_config('LD_IS_BFD', depends(enable_gold.KIND)(lambda x: x == 'bfd' or None)) -set_config('LINKER_LDFLAGS', enable_gold.LINKER_FLAG) +js_option('--enable-linker', nargs=1, + choices=('bfd', 'gold', 'lld', 'other'), + help='Select the linker', + when=build_not_win_mac) + +@depends('--enable-linker', c_compiler, developer_options, check_build_environment, when=build_not_win_mac) +@checking('for linker', lambda x: x.KIND) +def select_linker(linker, c_compiler, developer_options, build_env): + linker = linker[0] if linker else 'other' + if linker in ('gold', 'bfd', 'other'): + return enable_gnu_linker(linker == 'gold', c_compiler, developer_options, build_env, linker) + if linker == 'lld': + version_check = ['-Wl,--version'] + cmd_base = c_compiler.wrapper + [c_compiler.compiler] + c_compiler.flags + lld = "-fuse-ld=" + linker + cmd = cmd_base + [lld] + version_check + if 'LLD' in check_cmd_output(*cmd).decode('utf-8'): + return namespace( + KIND='lld', + LINKER_FLAG=lld, + ) + else: + die("Could not use lld as linker") + + +set_config('LD_IS_BFD', depends(select_linker.KIND)(lambda x: x == 'bfd' or None)) +set_config('LINKER_LDFLAGS', select_linker.LINKER_FLAG) From 9e809e01c262786664023bb3b77f8e378c0ade1e Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 3 Aug 2017 11:24:55 +1000 Subject: [PATCH 006/166] Bug 1377158 - (Part 1) Set style backend to stylo when SVG is used as an image. r=heycam MozReview-Commit-ID: 9FnA8X84h87 --HG-- extra : rebase_source : 49a6140c4c78c35f755710934c798ce46dafa213 --- dom/base/nsDocument.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 3585a7e222df..b4773160af92 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -13219,7 +13219,10 @@ nsIDocument::UpdateStyleBackendType() #ifdef MOZ_STYLO if (nsLayoutUtils::StyloEnabled()) { - if (!mDocumentContainer) { + if (IsBeingUsedAsImage()) { + // Enable stylo for SVG-as-image. + mStyleBackendType = StyleBackendType::Servo; + } else if (!mDocumentContainer) { NS_WARNING("stylo: No docshell yet, assuming Gecko style system"); } else if ((IsHTMLOrXHTML() || IsSVGDocument()) && IsContentDocument()) { From e418f1ccf520638dd1890da9d1f25235660ac0d2 Mon Sep 17 00:00:00 2001 From: KuoE0 Date: Mon, 24 Jul 2017 11:51:20 +0800 Subject: [PATCH 007/166] Bug 1377158 - (Part 2) Add the info of StyloEnabled() to hash function to make reftests of styloVsGecko get the correct caches. r=heycam MozReview-Commit-ID: 7cyXheHQ7Ot --HG-- extra : rebase_source : 4a92de63228cb2a138d95d8f366b39122dbdc05e --- image/ImageCacheKey.cpp | 20 ++++++++++++++++---- image/ImageCacheKey.h | 7 ++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/image/ImageCacheKey.cpp b/image/ImageCacheKey.cpp index c3327155c1cd..2dfdc7c763cc 100644 --- a/image/ImageCacheKey.cpp +++ b/image/ImageCacheKey.cpp @@ -8,6 +8,7 @@ #include "mozilla/Move.h" #include "ImageURL.h" #include "nsHostObjectProtocolHandler.h" +#include "nsLayoutUtils.h" #include "nsString.h" #include "mozilla/dom/File.h" #include "mozilla/dom/workers/ServiceWorkerManager.h" @@ -53,6 +54,7 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI, , mOriginAttributes(aAttrs) , mControlledDocument(GetControlledDocumentToken(aDocument)) , mIsChrome(URISchemeIs(mURI, "chrome")) + , mIsStyloEnabled(nsLayoutUtils::StyloEnabled()) { NS_ENSURE_SUCCESS_VOID(aRv); @@ -62,7 +64,8 @@ ImageCacheKey::ImageCacheKey(nsIURI* aURI, mBlobSerial = BlobSerial(mURI); } - mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); + mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument, + mIsStyloEnabled); } ImageCacheKey::ImageCacheKey(ImageURL* aURI, @@ -72,6 +75,7 @@ ImageCacheKey::ImageCacheKey(ImageURL* aURI, , mOriginAttributes(aAttrs) , mControlledDocument(GetControlledDocumentToken(aDocument)) , mIsChrome(URISchemeIs(mURI, "chrome")) + , mIsStyloEnabled(nsLayoutUtils::StyloEnabled()) { MOZ_ASSERT(aURI); @@ -79,7 +83,8 @@ ImageCacheKey::ImageCacheKey(ImageURL* aURI, mBlobSerial = BlobSerial(mURI); } - mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument); + mHash = ComputeHash(mURI, mBlobSerial, mOriginAttributes, mControlledDocument, + mIsStyloEnabled); } ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) @@ -89,6 +94,7 @@ ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) + , mIsStyloEnabled(aOther.mIsStyloEnabled) { } ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) @@ -98,11 +104,15 @@ ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther) , mControlledDocument(aOther.mControlledDocument) , mHash(aOther.mHash) , mIsChrome(aOther.mIsChrome) + , mIsStyloEnabled(aOther.mIsStyloEnabled) { } bool ImageCacheKey::operator==(const ImageCacheKey& aOther) const { + if (mIsStyloEnabled != aOther.mIsStyloEnabled) { + return false; + } // Don't share the image cache between a controlled document and anything else. if (mControlledDocument != aOther.mControlledDocument) { return false; @@ -132,7 +142,8 @@ ImageCacheKey::Spec() const ImageCacheKey::ComputeHash(ImageURL* aURI, const Maybe& aBlobSerial, const OriginAttributes& aAttrs, - void* aControlledDocument) + void* aControlledDocument, + bool aIsStyloEnabled) { // Since we frequently call Hash() several times in a row on the same // ImageCacheKey, as an optimization we compute our hash once and store it. @@ -142,7 +153,8 @@ ImageCacheKey::ComputeHash(ImageURL* aURI, aAttrs.CreateSuffix(suffix); return AddToHash(0, aURI->ComputeHash(aBlobSerial), - HashString(suffix), HashString(ptr)); + HashString(suffix), HashString(ptr), + aIsStyloEnabled); } /* static */ void* diff --git a/image/ImageCacheKey.h b/image/ImageCacheKey.h index c5acd0ea495e..6d676ccb6338 100644 --- a/image/ImageCacheKey.h +++ b/image/ImageCacheKey.h @@ -58,7 +58,8 @@ private: static PLDHashNumber ComputeHash(ImageURL* aURI, const Maybe& aBlobSerial, const OriginAttributes& aAttrs, - void* aControlledDocument); + void* aControlledDocument, + bool aIsStyloEnabled); static void* GetControlledDocumentToken(nsIDocument* aDocument); RefPtr mURI; @@ -67,6 +68,10 @@ private: void* mControlledDocument; PLDHashNumber mHash; bool mIsChrome; + // To prevent the reftests of styloVsGecko taking the same image cache after + // refreshing, we need to store different caches of stylo and gecko. So, we + // also consider the info of StyloEnabled() in ImageCacheKey. + bool mIsStyloEnabled; }; } // namespace image From c95ed14053c770c89928986f033d7494e74d102f Mon Sep 17 00:00:00 2001 From: KuoE0 Date: Thu, 27 Jul 2017 14:06:54 +0800 Subject: [PATCH 008/166] Bug 1377158 - (Part 3) Update the expectation of test cases. r=bholley,heycam MozReview-Commit-ID: K3gmTudkzol --HG-- extra : rebase_source : 32ba6ceb37fa2f29cde8d2534d73108e87dfa406 --- layout/reftests/css-break/reftest.list | 2 +- layout/reftests/svg/as-image/reftest.list | 2 +- layout/reftests/table-background/reftest.list | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/layout/reftests/css-break/reftest.list b/layout/reftests/css-break/reftest.list index 4364cf7d93fc..54cfbcbbeefc 100644 --- a/layout/reftests/css-break/reftest.list +++ b/layout/reftests/css-break/reftest.list @@ -2,7 +2,7 @@ default-preferences pref(layout.css.box-decoration-break.enabled,true) == box-decoration-break-1.html box-decoration-break-1-ref.html fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,4-4,3273-3273) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html -fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html +fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) fuzzy-if(styloVsGecko,1,420) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543 random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html == box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html == box-decoration-break-block-margin.html box-decoration-break-block-margin-ref.html diff --git a/layout/reftests/svg/as-image/reftest.list b/layout/reftests/svg/as-image/reftest.list index d5feb66693ad..acff18d18b50 100644 --- a/layout/reftests/svg/as-image/reftest.list +++ b/layout/reftests/svg/as-image/reftest.list @@ -58,7 +58,7 @@ fuzzy(1,2) fuzzy-if(azureSkia,1,40000) == canvas-drawImage-alpha-2.html canvas-d # context-fill: == context-fill-01.html blue100x100-ref.html test-pref(svg.context-properties.content.enabled,true) == context-fill-01.html lime100x100-ref.html -== context-fill-02.html transparent100x100-w-border-ref.html +fails-if(styloVsGecko||stylo) == context-fill-02.html transparent100x100-w-border-ref.html # Bug 1380590 test-pref(svg.context-properties.content.enabled,true) == context-fill-02.html lime100x100-w-border-ref.html test-pref(svg.context-properties.content.enabled,true) == context-fill-03.html lime100x100-50pct-ref.html # fuzz because on win8 the r & b components are off by one diff --git a/layout/reftests/table-background/reftest.list b/layout/reftests/table-background/reftest.list index d8a138112527..df2f629d0d7f 100644 --- a/layout/reftests/table-background/reftest.list +++ b/layout/reftests/table-background/reftest.list @@ -1,11 +1,11 @@ # these could be moved to crashtests != backgr_border-table-cell.html empty.html -!= backgr_border-table-column-group.html empty.html +fuzzy-if(styloVsGecko,5,330) != backgr_border-table-column-group.html empty.html # Bug 1386543 # This seems to be caused by bug 527825 -asserts-if(gtkWidget,0-12) != backgr_border-table-column.html empty.html +fuzzy-if(styloVsGecko,5,561) asserts-if(gtkWidget,0-12) != backgr_border-table-column.html empty.html # Bug 1386543 asserts-if(gtkWidget,0-6) != backgr_border-table-quirks.html empty.html -!= backgr_border-table-row-group.html empty.html -!= backgr_border-table-row.html empty.html +fuzzy-if(styloVsGecko,1,168) != backgr_border-table-row-group.html empty.html # Bug 1386543 +fuzzy-if(styloVsGecko,1,168) != backgr_border-table-row.html empty.html # Bug 1386543 != backgr_border-table.html empty.html != backgr_fixed-bg.html empty.html != backgr_index.html empty.html From dd7cb82fb7b50d4036aef4530520ea2583eea5fc Mon Sep 17 00:00:00 2001 From: KuoE0 Date: Fri, 28 Jul 2017 00:23:05 +0800 Subject: [PATCH 009/166] Bug 1377158 - (Part 4) Reduce the assertion cost to check reconstruction frame hint. r=bholley,heycam The original assertion took too long time to check nsStyleChangeList. It caused the test case with many elements timed-out and failed. MozReview-Commit-ID: FpNZvdQFTtR --HG-- extra : rebase_source : c68072448061c4dcc8399131924cf718a5e53700 --- layout/base/nsStyleChangeList.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/layout/base/nsStyleChangeList.cpp b/layout/base/nsStyleChangeList.cpp index 6f68cded3814..af6256f46c22 100644 --- a/layout/base/nsStyleChangeList.cpp +++ b/layout/base/nsStyleChangeList.cpp @@ -41,17 +41,25 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange (aHint & nsChangeHint_NeedReflow), "Reflow hint bits set without actually asking for a reflow"); - // If Servo fires reconstruct at a node, it is the only change hint fired at - // that node. - if (IsServo()) { - for (size_t i = 0; i < Length(); ++i) { - MOZ_ASSERT(!aContent || !((aHint | (*this)[i].mHint) & nsChangeHint_ReconstructFrame) || - (*this)[i].mContent != aContent); - } - } else { - // Filter out all other changes for same content for Gecko (Servo asserts against this - // case above). - if (aContent && (aHint & nsChangeHint_ReconstructFrame)) { + if (aContent && (aHint & nsChangeHint_ReconstructFrame)) { + // If Servo fires reconstruct at a node, it is the only change hint fired at + // that node. + if (IsServo()) { + // Note: Because we check whether |aHint| is a reconstruct above (which is + // necessary to avoid debug test timeouts on certain crashtests), this check + // will not find bugs where we add a non-reconstruct hint for an element after + // adding a reconstruct. This is ok though, since ProcessRestyledFrames will + // handle that case via mDestroyedFrames. + for (size_t i = 0; i < Length(); ++i) { + MOZ_ASSERT(aContent != (*this)[i].mContent || + !((*this)[i].mHint & nsChangeHint_ReconstructFrame), + "Should not append a non-ReconstructFrame hint after \ + appending a ReconstructFrame hint for the same \ + content."); + } + } else { + // Filter out all other changes for same content for Gecko (Servo asserts against this + // case above). // NOTE: This is captured by reference to please static analysis. // Capturing it by value as a pointer should be fine in this case. RemoveElementsBy([&](const nsStyleChangeData& aData) { From ea4858c92fa9faff187dcdeb76a8d2a8459f0e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 14:45:37 +0200 Subject: [PATCH 010/166] Bug 1362338: followup: Tentatively fix windows build bustage. r=me Windows apparently uses __stdcall for this, so need to use the ugly macros... MozReview-Commit-ID: 4J27sCYwdHg --- xpcom/ds/nsAtomTable.cpp | 4 ++-- xpcom/ds/nsIAtom.idl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 0bb2d7ab6451..2f3bde28990b 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -275,7 +275,7 @@ StaticAtom::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) //---------------------------------------------------------------------- -MozExternalRefCountType +NS_IMETHODIMP_(MozExternalRefCountType) nsIAtom::AddRef() { MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an nsHtml5Atom"); @@ -286,7 +286,7 @@ nsIAtom::AddRef() return static_cast(this)->DoAddRef(); } -MozExternalRefCountType +NS_IMETHODIMP_(MozExternalRefCountType) nsIAtom::Release() { MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an nsHtml5Atom"); diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index 0df64bfae49b..a050e7ee9113 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -95,8 +95,8 @@ interface nsIAtom : nsISupports return nsStringBuffer::FromData(mString); } - MozExternalRefCountType AddRef() final; - MozExternalRefCountType Release() final; + NS_IMETHOD_(MozExternalRefCountType) AddRef() final; + NS_IMETHOD_(MozExternalRefCountType) Release() final; /** * A hashcode that is better distributed than the actual atom From a68cdde16c1f99dfd6c43cffbd0cb6a257d9f932 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 15:09:45 +0100 Subject: [PATCH 011/166] Bug 1388365 - Upgrade to webdriver 0.29.0. r=whimboo Upgrades the webdriver crate dependency to 0.29.0, which contains some backwards incompatible changes for RectResponse. This type has been split in two, WindowRectResponse and ElementRectResponse. The former type contains a new "state" field which is already implemented by Marionette. Because geckodriver is used with a range of earlier Firefoxen, it defaults to "normal" window state if the field is not returned from Marionette. This is acceptable. MozReview-Commit-ID: FRxppRVmiZl --HG-- extra : rebase_source : 4a86659f337598bb4f5623c51f5df288c8a5dd69 --- testing/geckodriver/CHANGES.md | 12 +++++++++++- testing/geckodriver/Cargo.toml | 2 +- testing/geckodriver/src/marionette.rs | 17 ++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/testing/geckodriver/CHANGES.md b/testing/geckodriver/CHANGES.md index f66e301497c5..ecb97dceefea 100644 --- a/testing/geckodriver/CHANGES.md +++ b/testing/geckodriver/CHANGES.md @@ -4,8 +4,18 @@ All notable changes to this program is documented in this file. ## Unreleased +### Added +- New window `state` field on the window rect response object, returned from [`GetWindowRect`], [`SetWindowRect`], [`MinimizeWindow`], [`MaximizeWindow`], and [`FullscreenWindow`] commands + +[`FullscreenWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.FullscreenWindow +[`GetWindowRect`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.GetWindowRect +[`MaximizeWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.MaximizeWindow +[`MinimizeWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.MinimizeWindow +[`SetWindowRect`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.SetWindowRect + ### Changed -- `/moz/addon/install` command accepts an `addon` parameter, in lieu of `path`, containing an add-on as a base64 string. +- The `proxyType` `noproxy` has been replaced with `direct` in accordance with recent WebDriver specification changes +- `/moz/addon/install` command accepts an `addon` parameter, in lieu of `path`, containing an addon as a Base64 string ## 0.18.0 (2017-07-10) diff --git a/testing/geckodriver/Cargo.toml b/testing/geckodriver/Cargo.toml index 0450f77b4405..e4b6925dab42 100644 --- a/testing/geckodriver/Cargo.toml +++ b/testing/geckodriver/Cargo.toml @@ -27,7 +27,7 @@ slog-atomic = "0.4" slog-stdlog = "1" slog-stream = "1" uuid = "0.1.18" -webdriver = "0.28.0" +webdriver = "0.29.0" zip = "0.1" [[bin]] diff --git a/testing/geckodriver/src/marionette.rs b/testing/geckodriver/src/marionette.rs index 18ec911e8f21..369f9800fa38 100644 --- a/testing/geckodriver/src/marionette.rs +++ b/testing/geckodriver/src/marionette.rs @@ -45,9 +45,9 @@ use webdriver::command::{ GetNamedCookieParameters, AddCookieParameters, TimeoutsParameters, ActionsParameters, TakeScreenshotParameters}; use webdriver::response::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, - NewSessionResponse, RectResponse, TimeoutsResponse, ValueResponse, - WebDriverResponse}; -use webdriver::common::{Date, ELEMENT_KEY, FrameId, Nullable, WebElement}; + ElementRectResponse, NewSessionResponse, TimeoutsResponse, + ValueResponse, WebDriverResponse, WindowRectResponse}; +use webdriver::common::{Date, ELEMENT_KEY, FrameId, Nullable, WebElement, WindowState}; use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult}; use webdriver::server::{WebDriverHandler, Session}; use webdriver::httpapi::{WebDriverExtensionRoute}; @@ -757,7 +757,8 @@ impl MarionetteSession { ErrorStatus::UnknownError, "Failed to interpret width as float"); - WebDriverResponse::ElementRect(RectResponse::new(x, y, width, height)) + let rect = ElementRectResponse { x, y, width, height }; + WebDriverResponse::ElementRect(rect) }, FullscreenWindow | MinimizeWindow | MaximizeWindow | GetWindowRect | SetWindowRect(_) => { @@ -789,7 +790,13 @@ impl MarionetteSession { ErrorStatus::UnknownError, "Failed to interpret y as float"); - WebDriverResponse::WindowRect(RectResponse::new(x, y, width, height)) + let state = match resp.result.find("state") { + Some(json) => WindowState::from_json(json)?, + None => WindowState::Normal, + }; + + let rect = WindowRectResponse { x, y, width, height, state }; + WebDriverResponse::WindowRect(rect) }, GetCookies => { let cookies = try!(self.process_cookies(&resp.result)); From 8104c26b91cc0b16050e40a9408f340d2ca0eb48 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 15:10:55 +0100 Subject: [PATCH 012/166] Bug 1388365 - Vendor webdriver 0.29.0. r=whimboo MozReview-Commit-ID: 3vhk9kfmDHD --HG-- extra : rebase_source : 393c3ff983444bc8639d3ed94edce0b27dabe522 --- testing/geckodriver/Cargo.lock | 6 +- .../rust/webdriver/.cargo-checksum.json | 2 +- third_party/rust/webdriver/Cargo.toml | 22 ++-- .../rust/webdriver/src/capabilities.rs | 2 +- third_party/rust/webdriver/src/command.rs | 62 +++++----- third_party/rust/webdriver/src/common.rs | 64 +++++++++- third_party/rust/webdriver/src/error.rs | 2 +- third_party/rust/webdriver/src/httpapi.rs | 7 +- third_party/rust/webdriver/src/response.rs | 115 +++++++++++++----- third_party/rust/webdriver/src/server.rs | 4 +- 10 files changed, 197 insertions(+), 89 deletions(-) diff --git a/testing/geckodriver/Cargo.lock b/testing/geckodriver/Cargo.lock index b40017604efc..c3e55df36726 100644 --- a/testing/geckodriver/Cargo.lock +++ b/testing/geckodriver/Cargo.lock @@ -17,7 +17,7 @@ dependencies = [ "slog-stdlog 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stream 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", - "webdriver 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webdriver 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "zip 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -642,7 +642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "webdriver" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -770,7 +770,7 @@ dependencies = [ "checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum webdriver 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9238218a263593f2f143c32d10b0ddec2664a1f9b7be426eb775ee243af44739" +"checksum webdriver 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3aa46482421441f1954f5df7443a66e5744e8de22a3d825262157b109dbdd535" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winreg 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e63857fb213f619b4c4fff86b158285c76766aac7e7474967e92fb6dbbfeefe9" diff --git a/third_party/rust/webdriver/.cargo-checksum.json b/third_party/rust/webdriver/.cargo-checksum.json index 5d61866da3f0..5ae2b0e257fd 100644 --- a/third_party/rust/webdriver/.cargo-checksum.json +++ b/third_party/rust/webdriver/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"78252ef89a407b1d76616b7afbf7afb8205530a7f7039f3a7ea140684e3aa8bc","Cargo.toml":"74d24167dc8948953ab5c43b9a524b8ecff667c2f1ce9c0df539c1b799077998","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"bd0e99ce271903a9f67cf5f8fca2f67f2583e4336fbaf583fcd78ec238d4176e","src/capabilities.rs":"5039c1f80885ca2bab19f2d1c40b405c37c09901918625395141ac2e01600728","src/command.rs":"2e60c1b0eabccc3abef91574dbb94a4044a56fc1f4da18a45c6317c726480c2f","src/common.rs":"d696aabe88061f8315578c42115d976123a8fc4276384e478e14d241dfc9acc0","src/error.rs":"b0acf64e052edbc26e7dbcd1a54e8b9a786f01e9d48e0e5b2f410266bfdb9da2","src/httpapi.rs":"8e54ddc2796863ce7d9905484fb8214883a27a33bd94bee2ae765bccb9895f91","src/lib.rs":"336c146e934711dfe49f4b44bbcf278686b00be8d89abb9c7b7b045254994fbf","src/macros.rs":"93094c48e3880d925e684fba9678693eb8c0c39c7ed47b130b0751c4bca37ddc","src/response.rs":"63cabdc7f9136a0f24c10dc16b11c6991c95fd9fee1d1bc47d48c62c6f69eb33","src/server.rs":"f2110378cfaf7a4facb39d0e45c479a00c95a939536c85a6a105c858fffc2d70"},"package":"9238218a263593f2f143c32d10b0ddec2664a1f9b7be426eb775ee243af44739"} \ No newline at end of file +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"78252ef89a407b1d76616b7afbf7afb8205530a7f7039f3a7ea140684e3aa8bc","Cargo.toml":"b0f014ae89a79a1923c0209445f65935adf26fabbea19af22a62fc4c51bfb016","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"bd0e99ce271903a9f67cf5f8fca2f67f2583e4336fbaf583fcd78ec238d4176e","src/capabilities.rs":"3ced096444da586e077b0d62fb515f757e7809063e0c65fd7435678c8a8641b3","src/command.rs":"3538491c5e77746eca8d326185903f3336e47f75f69401167acbd655708e736a","src/common.rs":"79d50f6c29f16d370b707988fe7b1747e17372f979df75d30be3e250dce55836","src/error.rs":"7621e0c325c488b537e1bd26dd580b23863bf07bbae52cf8b77e6a7d37df47c3","src/httpapi.rs":"83fec1cefedbadb8bf7458374f909a44ff76d67046e8428fc01067d5d8401dc6","src/lib.rs":"336c146e934711dfe49f4b44bbcf278686b00be8d89abb9c7b7b045254994fbf","src/macros.rs":"93094c48e3880d925e684fba9678693eb8c0c39c7ed47b130b0751c4bca37ddc","src/response.rs":"160bc15135d623d1bc5b33c6edaf69a4034d36c1cd8d9cefb64f436001dda01e","src/server.rs":"4f8976a215783c98f1e3927e5440590fe3a41189bf62fea151434598f904753c"},"package":"3aa46482421441f1954f5df7443a66e5744e8de22a3d825262157b109dbdd535"} \ No newline at end of file diff --git a/third_party/rust/webdriver/Cargo.toml b/third_party/rust/webdriver/Cargo.toml index 809ce3a66755..986d482b61a0 100644 --- a/third_party/rust/webdriver/Cargo.toml +++ b/third_party/rust/webdriver/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "webdriver" -version = "0.28.0" +version = "0.29.0" authors = ["Mozilla Tools and Automation "] description = "Library implementing the wire protocol for the W3C WebDriver specification" documentation = "https://docs.rs/webdriver" @@ -20,14 +20,17 @@ readme = "README.md" keywords = ["webdriver", "browser", "automation", "protocol", "w3c"] license = "MPL-2.0" repository = "https://github.com/mozilla/webdriver-rust" +[dependencies.regex] +version = "0.2" + +[dependencies.url] +version = "1" + [dependencies.log] version = "0.3" -[dependencies.backtrace] -version = "0.3" - -[dependencies.regex] -version = "0.2" +[dependencies.hyper] +version = "0.10" [dependencies.rustc-serialize] version = "0.3" @@ -39,8 +42,5 @@ default-features = false [dependencies.time] version = "0.1" -[dependencies.hyper] -version = "0.10" - -[dependencies.url] -version = "1" +[dependencies.backtrace] +version = "0.3" diff --git a/third_party/rust/webdriver/src/capabilities.rs b/third_party/rust/webdriver/src/capabilities.rs index eb159417f879..a25e6820699f 100644 --- a/third_party/rust/webdriver/src/capabilities.rs +++ b/third_party/rust/webdriver/src/capabilities.rs @@ -149,7 +149,7 @@ impl SpecNewSessionParameters { match &**key { "proxyType" => match value.as_string() { Some("pac") | - Some("noproxy") | + Some("direct") | Some("autodetect") | Some("system") | Some("manual") => {}, diff --git a/third_party/rust/webdriver/src/command.rs b/third_party/rust/webdriver/src/command.rs index ee161924885f..ce0f15ab4d80 100644 --- a/third_party/rust/webdriver/src/command.rs +++ b/third_party/rust/webdriver/src/command.rs @@ -9,7 +9,7 @@ use rustc_serialize::json::{ToJson, Json}; use std::collections::BTreeMap; use std::default::Default; -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum WebDriverCommand { NewSession(NewSessionParameters), DeleteSession, @@ -74,7 +74,7 @@ pub trait WebDriverExtensionCommand : Clone + Send + PartialEq { fn parameters_json(&self) -> Option; } -#[derive(Clone, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct VoidWebDriverExtensionCommand; impl WebDriverExtensionCommand for VoidWebDriverExtensionCommand { @@ -83,7 +83,7 @@ impl WebDriverExtensionCommand for VoidWebDriverExtensionCommand { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct WebDriverMessage { pub session_id: Option, pub command: WebDriverCommand, @@ -490,7 +490,7 @@ impl CapabilitiesMatching for NewSessionParameters { } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct GetParameters { pub url: String } @@ -519,7 +519,7 @@ impl ToJson for GetParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct TimeoutsParameters { pub script: Option, pub page_load: Option, @@ -658,7 +658,7 @@ impl ToJson for WindowRectParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct SwitchToWindowParameters { pub handle: String } @@ -687,7 +687,7 @@ impl ToJson for SwitchToWindowParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct LocatorParameters { pub using: LocatorStrategy, pub value: String @@ -726,7 +726,7 @@ impl ToJson for LocatorParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct SwitchToFrameParameters { pub id: FrameId } @@ -754,7 +754,7 @@ impl ToJson for SwitchToFrameParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct SendKeysParameters { pub text: String } @@ -784,7 +784,7 @@ impl ToJson for SendKeysParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct JavascriptCommandParameters { pub script: String, pub args: Nullable> @@ -832,7 +832,7 @@ impl ToJson for JavascriptCommandParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct GetNamedCookieParameters { pub name: Nullable, } @@ -863,7 +863,7 @@ impl ToJson for GetNamedCookieParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct AddCookieParameters { pub name: String, pub value: String, @@ -978,7 +978,7 @@ impl ToJson for AddCookieParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct TakeScreenshotParameters { pub element: Nullable } @@ -1011,7 +1011,7 @@ impl ToJson for TakeScreenshotParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct ActionsParameters { pub actions: Vec } @@ -1047,7 +1047,7 @@ impl ToJson for ActionsParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct ActionSequence { pub id: Nullable, pub actions: ActionsType @@ -1113,7 +1113,7 @@ impl ToJson for ActionSequence { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum ActionsType { Null(Vec), Key(Vec), @@ -1162,7 +1162,7 @@ impl Parameters for ActionsType { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum PointerType { Mouse, Pen, @@ -1203,7 +1203,7 @@ impl Default for PointerType { } } -#[derive(Default, PartialEq)] +#[derive(Debug, Default, PartialEq)] pub struct PointerActionParameters { pub pointer_type: PointerType } @@ -1232,7 +1232,7 @@ impl ToJson for PointerActionParameters { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum NullActionItem { General(GeneralAction) } @@ -1265,7 +1265,7 @@ impl ToJson for NullActionItem { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum KeyActionItem { General(GeneralAction), Key(KeyAction) @@ -1300,7 +1300,7 @@ impl ToJson for KeyActionItem { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum PointerActionItem { General(GeneralAction), Pointer(PointerAction) @@ -1334,7 +1334,7 @@ impl ToJson for PointerActionItem { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum GeneralAction { Pause(PauseAction) } @@ -1357,7 +1357,7 @@ impl ToJson for GeneralAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct PauseAction { pub duration: u64 } @@ -1384,7 +1384,7 @@ impl ToJson for PauseAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum KeyAction { Up(KeyUpAction), Down(KeyDownAction) @@ -1427,7 +1427,7 @@ fn validate_key_value(value_str: &str) -> WebDriverResult { Ok(value) } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct KeyUpAction { pub value: char } @@ -1459,7 +1459,7 @@ impl ToJson for KeyUpAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct KeyDownAction { pub value: char } @@ -1490,7 +1490,7 @@ impl ToJson for KeyDownAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum PointerOrigin { Viewport, Pointer, @@ -1531,7 +1531,7 @@ impl Default for PointerOrigin { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum PointerAction { Up(PointerUpAction), Down(PointerDownAction), @@ -1569,7 +1569,7 @@ impl ToJson for PointerAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct PointerUpAction { pub button: u64, } @@ -1599,7 +1599,7 @@ impl ToJson for PointerUpAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct PointerDownAction { pub button: u64, } @@ -1629,7 +1629,7 @@ impl ToJson for PointerDownAction { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct PointerMoveAction { pub duration: Nullable, pub origin: PointerOrigin, diff --git a/third_party/rust/webdriver/src/common.rs b/third_party/rust/webdriver/src/common.rs index a57e3bbc5ce9..718c49b5c95a 100644 --- a/third_party/rust/webdriver/src/common.rs +++ b/third_party/rust/webdriver/src/common.rs @@ -6,7 +6,7 @@ use error::{WebDriverResult, WebDriverError, ErrorStatus}; pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf"; -#[derive(RustcEncodable, PartialEq, Clone, Debug)] +#[derive(Clone, Debug, PartialEq, RustcEncodable)] pub struct Date(pub u64); impl Date { @@ -22,7 +22,7 @@ impl ToJson for Date { } } -#[derive(PartialEq, Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum Nullable { Value(T), Null @@ -142,7 +142,7 @@ impl From for WebElement } } -#[derive(PartialEq, Debug)] +#[derive(Debug, PartialEq)] pub enum FrameId { Short(u16), Element(WebElement), @@ -184,19 +184,19 @@ impl ToJson for FrameId { } } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum LocatorStrategy { CSSSelector, LinkText, PartialLinkText, - XPath + XPath, } impl LocatorStrategy { pub fn from_json(body: &Json) -> WebDriverResult { match try_opt!(body.as_string(), ErrorStatus::InvalidArgument, - "Cound not convert strategy to string") { + "Expected locator strategy as string") { "css selector" => Ok(LocatorStrategy::CSSSelector), "link text" => Ok(LocatorStrategy::LinkText), "partial link text" => Ok(LocatorStrategy::PartialLinkText), @@ -217,3 +217,55 @@ impl ToJson for LocatorStrategy { }.to_string()) } } + +/// The top-level browsing context has an associated window state which +/// describes what visibility state its OS widget window is in. +/// +/// The default state is [`Normal`]. +/// +/// [`normal`]: #variant.Normal +#[derive(Debug)] +pub enum WindowState { + /// The window is maximized. + Maximized, + /// The window is iconified. + Minimized, + /// The window is shown normally. + Normal, + /// The window is in full screen mode. + Fullscreen, +} + +impl WindowState { + pub fn from_json(body: &Json) -> WebDriverResult { + use self::WindowState::*; + let s = try_opt!( + body.as_string(), + ErrorStatus::InvalidArgument, + "Expecetd window state as string" + ); + match s { + "maximized" => Ok(Maximized), + "minimized" => Ok(Minimized), + "normal" => Ok(Normal), + "fullscreen" => Ok(Fullscreen), + x => Err(WebDriverError::new( + ErrorStatus::InvalidArgument, + format!("Unknown window state {}", x), + )), + } + } +} + +impl ToJson for WindowState { + fn to_json(&self) -> Json { + use self::WindowState::*; + let state = match *self { + Maximized => "maximized", + Minimized => "minimized", + Normal => "normal", + Fullscreen => "fullscreen", + }; + Json::String(state.to_string()) + } +} diff --git a/third_party/rust/webdriver/src/error.rs b/third_party/rust/webdriver/src/error.rs index 91eb4fe0975a..1ca0af8f66a0 100644 --- a/third_party/rust/webdriver/src/error.rs +++ b/third_party/rust/webdriver/src/error.rs @@ -9,7 +9,7 @@ use std::error::Error; use std::fmt; use std::io; -#[derive(PartialEq, Debug)] +#[derive(Debug, PartialEq)] pub enum ErrorStatus { /// The [`ElementClick`] command could not be completed because the /// [element] receiving the events is obscuring the element that was diff --git a/third_party/rust/webdriver/src/httpapi.rs b/third_party/rust/webdriver/src/httpapi.rs index 8f330440a4b4..f16a440acfda 100644 --- a/third_party/rust/webdriver/src/httpapi.rs +++ b/third_party/rust/webdriver/src/httpapi.rs @@ -71,7 +71,7 @@ fn standard_routes() -> Vec<(Method, &'static str, Ro (Get, "/status", Route::Status),] } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum Route { NewSession, DeleteSession, @@ -142,7 +142,7 @@ pub trait WebDriverExtensionRoute : Clone + Send + PartialEq { fn command(&self, &Captures, &Json) -> WebDriverResult>; } -#[derive(Clone, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub struct VoidWebDriverExtensionRoute; impl WebDriverExtensionRoute for VoidWebDriverExtensionRoute { @@ -153,7 +153,7 @@ impl WebDriverExtensionRoute for VoidWebDriverExtensionRoute { } } -#[derive(Clone)] +#[derive(Clone, Debug)] struct RequestMatcher { method: Method, path_regexp: Regex, @@ -197,6 +197,7 @@ impl RequestMatcher { } } +#[derive(Debug)] pub struct WebDriverHttpApi { routes: Vec<(Method, RequestMatcher)>, } diff --git a/third_party/rust/webdriver/src/response.rs b/third_party/rust/webdriver/src/response.rs index 1f4d5e64664a..5159891bb241 100644 --- a/third_party/rust/webdriver/src/response.rs +++ b/third_party/rust/webdriver/src/response.rs @@ -1,7 +1,7 @@ -use rustc_serialize::json::{self, Json, ToJson}; - -use common::{Nullable, Date}; +use common::{Date, Nullable, WindowState}; use cookie; +use rustc_serialize::json::{self, Json, ToJson}; +use std::collections::BTreeMap; use time; #[derive(Debug)] @@ -10,12 +10,12 @@ pub enum WebDriverResponse { Cookie(CookieResponse), Cookies(CookiesResponse), DeleteSession, - ElementRect(RectResponse), + ElementRect(ElementRectResponse), Generic(ValueResponse), NewSession(NewSessionResponse), Timeouts(TimeoutsResponse), Void, - WindowRect(RectResponse), + WindowRect(WindowRectResponse), } impl WebDriverResponse { @@ -32,7 +32,7 @@ impl WebDriverResponse { NewSession(ref x) => json::encode(x), Timeouts(ref x) => json::encode(x), Void => Ok("{}".to_string()), - WindowRect(ref x) => json::encode(x), + WindowRect(ref x) => json::encode(&x.to_json()), }.unwrap(); match self { @@ -48,7 +48,7 @@ impl WebDriverResponse { } } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct CloseWindowResponse { pub window_handles: Vec, } @@ -68,7 +68,7 @@ impl ToJson for CloseWindowResponse { } } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct NewSessionResponse { pub sessionId: String, pub capabilities: json::Json @@ -83,7 +83,7 @@ impl NewSessionResponse { } } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct TimeoutsResponse { pub script: u64, pub pageLoad: u64, @@ -100,7 +100,7 @@ impl TimeoutsResponse { } } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct ValueResponse { pub value: json::Json } @@ -113,26 +113,70 @@ impl ValueResponse { } } -#[derive(RustcEncodable, Debug)] -pub struct RectResponse { +#[derive(Debug, RustcEncodable)] +pub struct ElementRectResponse { + /// X axis position of the top-left corner of the element relative + // to the current browsing context’s document element in CSS reference + // pixels. pub x: f64, + + /// Y axis position of the top-left corner of the element relative + // to the current browsing context’s document element in CSS reference + // pixels. pub y: f64, + + /// Height of the element’s [bounding rectangle] in CSS reference + /// pixels. + /// + /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle pub width: f64, - pub height: f64 + + /// Width of the element’s [bounding rectangle] in CSS reference + /// pixels. + /// + /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle + pub height: f64, } -impl RectResponse { - pub fn new(x: f64, y: f64, width: f64, height: f64) -> RectResponse { - RectResponse { - x: x, - y: y, - width: width, - height: height - } +#[derive(Debug)] +pub struct WindowRectResponse { + /// `WindowProxy`’s [screenX] attribute. + /// + /// [screenX]: https://drafts.csswg.org/cssom-view/#dom-window-screenx + pub x: f64, + + /// `WindowProxy`’s [screenY] attribute. + /// + /// [screenY]: https://drafts.csswg.org/cssom-view/#dom-window-screeny + pub y: f64, + + /// Width of the top-level browsing context’s outer dimensions, including + /// any browser chrome and externally drawn window decorations in CSS + /// reference pixels. + pub width: f64, + + /// Height of the top-level browsing context’s outer dimensions, including + /// any browser chrome and externally drawn window decorations in CSS + /// reference pixels. + pub height: f64, + + /// The top-level browsing context’s window state. + pub state: WindowState, +} + +impl ToJson for WindowRectResponse { + fn to_json(&self) -> Json { + let mut body = BTreeMap::new(); + body.insert("x".to_owned(), self.x.to_json()); + body.insert("y".to_owned(), self.y.to_json()); + body.insert("width".to_owned(), self.width.to_json()); + body.insert("height".to_owned(), self.height.to_json()); + body.insert("state".to_owned(), self.state.to_json()); + Json::Object(body) } } -#[derive(RustcEncodable, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, PartialEq, RustcEncodable)] pub struct Cookie { pub name: String, pub value: String, @@ -166,20 +210,22 @@ impl Into> for Cookie { } } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct CookieResponse { pub value: Cookie, } -#[derive(RustcEncodable, Debug)] +#[derive(Debug, RustcEncodable)] pub struct CookiesResponse { pub value: Vec, } #[cfg(test)] mod tests { - use super::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, NewSessionResponse, - Nullable, RectResponse, TimeoutsResponse, ValueResponse, WebDriverResponse}; + use super::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, ElementRectResponse, + NewSessionResponse, Nullable, TimeoutsResponse, ValueResponse, WebDriverResponse, + WindowRectResponse}; + use common::WindowState; use rustc_serialize::json::Json; use std::collections::BTreeMap; @@ -236,21 +282,28 @@ mod tests { #[test] fn test_element_rect() { - let resp = WebDriverResponse::ElementRect(RectResponse::new( - 0f64, 1f64, 2f64, 3f64)); + let rect = ElementRectResponse { + x: 0f64, + y: 1f64, + width: 2f64, + height: 3f64, + }; + let resp = WebDriverResponse::ElementRect(rect); let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0}}"#; test(resp, expected); } #[test] fn test_window_rect() { - let resp = WebDriverResponse::WindowRect(RectResponse { + let rect = WindowRectResponse { x: 0f64, y: 1f64, width: 2f64, height: 3f64, - }); - let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0}}"#; + state: WindowState::Normal, + }; + let resp = WebDriverResponse::WindowRect(rect); + let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0, "state": "normal"}}"#; test(resp, expected); } diff --git a/third_party/rust/webdriver/src/server.rs b/third_party/rust/webdriver/src/server.rs index d451ed2d5648..f4e892510353 100644 --- a/third_party/rust/webdriver/src/server.rs +++ b/third_party/rust/webdriver/src/server.rs @@ -23,7 +23,7 @@ enum DispatchMessage { Quit } -#[derive(PartialEq, Clone)] +#[derive(Clone, Debug, PartialEq)] pub struct Session { id: String } @@ -41,6 +41,7 @@ pub trait WebDriverHandler); } +#[derive(Debug)] struct Dispatcher, U: WebDriverExtensionRoute> { handler: T, @@ -148,6 +149,7 @@ impl, U: WebDriverExtensionRoute> Dispatcher { } } +#[derive(Debug)] struct HttpHandler { chan: Mutex>>, api: Mutex> From 69dc2e2dfa76004cab497b64acee412ee4be00dd Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 14:57:24 +0100 Subject: [PATCH 013/166] Bug 1388365 - Return window to normal state. r=whimboo If a test leaves the window in maximized, minimized, or fullscreen state it should be returned to the normal state the next time a session is requested. MozReview-Commit-ID: IALlITFVz1w --HG-- extra : rebase_source : df1944bc73d967fa9ff0fe4e60e7815044afef0b --- .../tests/webdriver/tests/support/fixtures.py | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/testing/web-platform/tests/webdriver/tests/support/fixtures.py b/testing/web-platform/tests/webdriver/tests/support/fixtures.py index e44c5377c9ab..0265ddbe1ab8 100644 --- a/testing/web-platform/tests/webdriver/tests/support/fixtures.py +++ b/testing/web-platform/tests/webdriver/tests/support/fixtures.py @@ -13,7 +13,10 @@ default_host = "http://127.0.0.1" default_port = "4444" def _ensure_valid_window(session): - """If current window is not open anymore, ensure to have a valid one selected.""" + """If current window is not open anymore, ensure to have a valid + one selected. + + """ try: session.window_handle except webdriver.NoSuchWindowException: @@ -34,6 +37,20 @@ def _dismiss_user_prompts(session): session.window_handle = current_window +def _restore_normal_window_state(session): + """If the window is maximized, minimized, or fullscreened it will + be returned to normal state. + + """ + state = session.window.state + if state == "maximized": + session.window.maximize() + elif state == "minimized": + session.window.minimize() + elif state == "fullscreen": + session.window.fullscreen() + + def _restore_windows(session): """Closes superfluous windows opened by the test without ending the session implicitly by closing the last window. @@ -135,6 +152,7 @@ def session(configuration, request): # finalisers are popped off a stack, # making their ordering reverse request.addfinalizer(lambda: _switch_to_top_level_browsing_context(_current_session)) + request.addfinalizer(lambda: _restore_normal_window_state(_current_session)) request.addfinalizer(lambda: _restore_windows(_current_session)) request.addfinalizer(lambda: _dismiss_user_prompts(_current_session)) request.addfinalizer(lambda: _ensure_valid_window(_current_session)) From df65a930256b7621fc1a1afce447e6c28ac4a9b1 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 14:59:09 +0100 Subject: [PATCH 014/166] Bug 1388365 - Add client.Window#state and #rect. r=whimboo Introduces two new APIs on client.Window in the WPT WebDriver client: client.Window#state and client.Window#rect. The latter is used to reduce raw calls amongst client.Window's shorthands to GET window/rect. MozReview-Commit-ID: Kf4P2q93QaL --HG-- extra : rebase_source : cd38db307a3db08c0cc94eb7adb582bd885987e2 --- .../tests/tools/webdriver/webdriver/client.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/client.py b/testing/web-platform/tests/tools/webdriver/webdriver/client.py index 50af6189e395..f1a7e9f94569 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/client.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/client.py @@ -237,11 +237,16 @@ class Window(object): def __init__(self, session): self.session = session + @property + @command + def rect(self): + return self.session.send_session_command("GET", "window/rect") + @property @command def size(self): - resp = self.session.send_session_command("GET", "window/rect") - return (resp["width"], resp["height"]) + rect = self.rect + return (rect["width"], rect["height"]) @size.setter @command @@ -253,8 +258,8 @@ class Window(object): @property @command def position(self): - resp = self.session.send_session_command("GET", "window/rect") - return (resp["x"], resp["y"]) + rect = self.rect + return (rect["x"], rect["y"]) @position.setter @command @@ -263,6 +268,11 @@ class Window(object): body = {"x": x, "y": y} self.session.send_session_command("POST", "window/rect", body) + @property + @command + def state(self): + return self.rect["state"] + @command def maximize(self): return self.session.send_session_command("POST", "window/maximize") From ba1a5cc488545e4fc948c2b80fb511ceb7ce76d3 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 15:36:38 +0100 Subject: [PATCH 015/166] Bug 1388365 - Add minimize and fullscreen to client.Window. r=whimboo MozReview-Commit-ID: KMqJmnAwGEY --HG-- extra : rebase_source : 1a738b28dd470c9a2df765f87eac4375539570fa --- .../tests/tools/webdriver/webdriver/client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/client.py b/testing/web-platform/tests/tools/webdriver/webdriver/client.py index f1a7e9f94569..86e687930f9a 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/client.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/client.py @@ -277,6 +277,14 @@ class Window(object): def maximize(self): return self.session.send_session_command("POST", "window/maximize") + @command + def minimize(self): + return self.session.send_session_command("POST", "window/minimize") + + @command + def fullscreen(self): + return self.session.send_session_command("POST", "window/fullscreen") + class Find(object): def __init__(self, session): From f21cc713c4c6790e3a6370a96ef57cd1f01c60d1 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 15:37:15 +0100 Subject: [PATCH 016/166] Bug 1388365 - Return value from assert_success. r=whimboo Return the contents of value, if it exists, after asserting the response was successful. assert_success can be passed a value which will assert that the response's value matches an expected value. If you want to compare a subsection of the response it may be convenient to for the value to be returned after it has been asserted that the response was a success. MozReview-Commit-ID: 1dyzQIazYEN --HG-- extra : rebase_source : f628f1fa144ccfd026b21df1b4bc2e748b08413c --- testing/web-platform/tests/webdriver/tests/support/asserts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/web-platform/tests/webdriver/tests/support/asserts.py b/testing/web-platform/tests/webdriver/tests/support/asserts.py index 0d15964c9bba..f3318010aa31 100644 --- a/testing/web-platform/tests/webdriver/tests/support/asserts.py +++ b/testing/web-platform/tests/webdriver/tests/support/asserts.py @@ -80,6 +80,7 @@ def assert_success(response, value=None): assert response.status == 200 if value is not None: assert response.body["value"] == value + return response.body.get("value") def assert_dialog_handled(session, expected_text): result = session.transport.send("GET", From 17551fc78974f2a1c1f6b5f43f837fd03df20574 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 8 Aug 2017 14:59:37 +0100 Subject: [PATCH 017/166] Bug 1388365 - Test window rect state. r=whimboo MozReview-Commit-ID: 1MoA370SUeW --HG-- extra : rebase_source : 7c387709ea637c479a5533cce55f4a9715c2645a --- .../tests/webdriver/tests/maximize_window.py | 31 ++-- .../tests/webdriver/tests/set_window_rect.py | 132 ++++++++++-------- 2 files changed, 90 insertions(+), 73 deletions(-) diff --git a/testing/web-platform/tests/webdriver/tests/maximize_window.py b/testing/web-platform/tests/webdriver/tests/maximize_window.py index 82b8642ea1ce..91b1383a77bd 100644 --- a/testing/web-platform/tests/webdriver/tests/maximize_window.py +++ b/testing/web-platform/tests/webdriver/tests/maximize_window.py @@ -20,18 +20,20 @@ def test_handle_user_prompt(session): def test_maximize(session): - before = session.window.size + before_size = session.window.size + assert session.window.state == "normal" # step 4 result = session.transport.send("POST", "session/%s/window/maximize" % session.session_id) assert_success(result) - after = session.window.size - assert before != after + assert before_size != session.window.size + assert session.window.state == "maximized" def test_payload(session): - before = session.window.size + before_size = session.window.size + assert session.window.state == "normal" result = session.transport.send("POST", "session/%s/window/maximize" % session.session_id) @@ -44,13 +46,15 @@ def test_payload(session): assert "height" in rect assert "x" in rect assert "y" in rect - assert isinstance(rect["width"], float) - assert isinstance(rect["height"], float) - assert isinstance(rect["x"], float) - assert isinstance(rect["y"], float) + assert "state" in rect + assert isinstance(rect["width"], (int, float)) + assert isinstance(rect["height"], (int, float)) + assert isinstance(rect["x"], (int, float)) + assert isinstance(rect["y"], (int, float)) + assert isinstance(rect["state"], basestring) - after = session.window.size - assert before != after + assert before_size != session.window.size + assert session.window.state == "maximized" def test_maximize_when_resized_to_max_size(session): @@ -59,7 +63,9 @@ def test_maximize_when_resized_to_max_size(session): # # Then resize the window to the maximum available size. session.end() + assert session.window.state == "normal" available = session.window.maximize() + assert session.window.state == "maximized" session.end() session.window.size = (int(available["width"]), int(available["height"])) @@ -69,7 +75,8 @@ def test_maximize_when_resized_to_max_size(session): # since this is often a special state. If a remote end expects a DOM # resize event, this may not fire if the window has already reached # its expected dimensions. + assert session.window.state == "normal" before = session.window.size session.window.maximize() - after = session.window.size - assert before == after + assert session.window.size == before + assert session.window.state == "maximized" diff --git a/testing/web-platform/tests/webdriver/tests/set_window_rect.py b/testing/web-platform/tests/webdriver/tests/set_window_rect.py index afb7785e1f87..2b52a8e1dae4 100644 --- a/testing/web-platform/tests/webdriver/tests/set_window_rect.py +++ b/testing/web-platform/tests/webdriver/tests/set_window_rect.py @@ -102,26 +102,24 @@ def test_set_window_rect_invalid_params(session, data): def test_set_window_fullscreen(session): - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + original = session.window.rect # step 10 - session.transport.send("POST", - "session/%s/window/fullscreen" % session.session_id) - assert session.execute_script("return document.fullscreenElement != null") + session.window.fullscreen() + assert session.window.state == "fullscreen" result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, {"width": 400, "height": 400}) - assert session.execute_script("return document.fullscreenElement == null") assert_success(result, {"x": original["x"], "y": original["y"], - "width": 400, - "height": 400}) + "width": 400.0, + "height": 400.0, + "state": "normal"}) def test_set_window_rect_window_minimized(session): # step 11 - session.minimize() + session.window.minimize() assert session.execute_script("return document.hidden") result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, @@ -131,123 +129,132 @@ def test_set_window_rect_window_minimized(session): def test_set_window_height_width(session): - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + original = session.window.rect - # Step 12 - _max = session.execute_script(""" + # step 12 + max = session.execute_script(""" return { width: window.screen.availWidth, height: window.screen.availHeight, }""") result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, - {"width": _max["width"] - 100, - "height": _max["height"] - 100}) + {"width": max["width"] - 100, + "height": max["height"] - 100}) - # Step 14 - assert_success(result, {"x": original["x"], "y": original["y"], - "width": _max["width"] - 100, - "height": _max["height"] - 100}) + # step 14 + assert_success(result, {"x": original["x"], + "y": original["y"], + "width": max["width"] - 100, + "height": max["height"] - 100, + "state": "normal"}) def test_set_window_height_width_larger_than_max(session): - # Step 12 - _max = session.execute_script(""" + # step 12 + max = session.execute_script(""" return { width: window.screen.availWidth, height: window.screen.availHeight, }""") result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, - {"width": _max["width"] + 100, - "height": _max["width"] + 100}) + {"width": max["width"] + 100, + "height": max["width"] + 100}) # Step 14 assert result.status == 200 - assert result.body["value"]["width"] >= _max["width"] - assert result.body["value"]["height"] >= _max["height"] + rect = result.body["value"] + assert rect["width"] >= max["width"] + assert rect["height"] >= max["height"] + assert rect["state"] == "normal" def test_set_window_height_width_as_current(session): - # Step 12 - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + # step 12 + original = session.window.rect result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, {"width": int(original["width"]), "height": int(original["height"])}) - # Step 14 + # step 14 assert_success(result, {"x": original["x"], "y": original["y"], "width": original["width"], - "height": original["height"]}) + "height": original["height"], + "state": original["state"]}) def test_set_window_rect_x_y(session): - # Step 13 - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + # step 13 + original = session.window.rect result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, {"x": int(original["x"]) + 10, "y": int(original["y"]) + 10}) - # Step 14 + # step 14 assert_success(result, {"x": original["x"] + 10, "y": original["y"] + 10, "width": original["width"], - "height": original["height"]}) + "height": original["height"], + "state": original["state"]}) def test_set_window_rect_negative_x_y(session): - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + original = session.window.rect - # Step 13 + # step 13 result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, {"x": - 8, "y": - 8}) + # step 14 + os = session.capabilities["platformName"] - # Step 14 + # certain WMs prohibit windows from being moved off-screen if os == "linux": - # certain WMs prohibit windows from being moved off-screen - assert_success(result, {"x": 0, "y": 0, - "width": original["width"], - "height": original["height"]}) + rect = assert_success(result) + assert rect["x"] <= 0 + assert rect["y"] <= 0 + assert rect["width"] == original["width"] + assert rect["height"] == original["height"] + assert rect["state"] == original["state"] # On macOS, windows can only be moved off the screen on the # horizontal axis. The system menu bar also blocks windows from # being moved to (0,0). elif os == "darwin": - assert_success(result, {"x": -8, "y": 23, + assert_success(result, {"x": -8, + "y": 23, "width": original["width"], - "height": original["height"]}) + "height": original["height"], + "state": original["state"]}) # It turns out that Windows is the only platform on which the # window can be reliably positioned off-screen. elif os == "windows_nt": - assert_success(result, {"x": -8, "y": -8, + assert_success(result, {"x": -8, + "y": -8, "width": original["width"], - "height": original["height"]}) - + "height": original["height"], + "state": original["state"]}) def test_set_window_x_y_as_current(session): - # Step 13 - get_response = session.transport.send("GET", "session/%s/window/rect" % session.session_id) - original = get_response.body["value"] + # step 13 + original = session.window.rect result = session.transport.send("POST", "session/%s/window/rect" % session.session_id, {"x": int(original["x"]), "y": int(original["y"])}) - # Step 14 + # step 14 assert_success(result, {"x": original["x"], "y": original["y"], "width": original["width"], - "height": original["height"]}) + "height": original["height"], + "state": original["state"]}) def test_set_window_rect_payload(session): # step 14 @@ -258,11 +265,14 @@ def test_set_window_rect_payload(session): assert result.status == 200 assert isinstance(result.body["value"], dict) - assert "width" in result.body["value"] - assert "height" in result.body["value"] - assert "x" in result.body["value"] - assert "y" in result.body["value"] - assert isinstance(result.body["value"]["width"], (int, float)) - assert isinstance(result.body["value"]["height"], (int, float)) - assert isinstance(result.body["value"]["x"], (int, float)) - assert isinstance(result.body["value"]["y"], (int, float)) + rect = result.body["value"] + assert "width" in rect + assert "height" in rect + assert "x" in rect + assert "y" in rect + assert "state" in rect + assert isinstance(rect["width"], (int, float)) + assert isinstance(rect["height"], (int, float)) + assert isinstance(rect["x"], (int, float)) + assert isinstance(rect["y"], (int, float)) + assert isinstance(rect["state"], basestring) From 04f22c3207da9173b529cbe128e43a6e764d6d7b Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Wed, 9 Aug 2017 14:16:27 +0100 Subject: [PATCH 018/166] Bug 1388725 - Fix add_task in SpawnTask.js to give a useful crash for unhandled exceptions. r=jmaher MozReview-Commit-ID: 6ZTKhi1eZ4P --HG-- extra : rebase_source : 86e90eeaca6410765d0795f323919df921e8799d --- testing/mochitest/tests/SimpleTest/SpawnTask.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/mochitest/tests/SimpleTest/SpawnTask.js b/testing/mochitest/tests/SimpleTest/SpawnTask.js index de14a03e8279..b197a97d30a2 100644 --- a/testing/mochitest/tests/SimpleTest/SpawnTask.js +++ b/testing/mochitest/tests/SimpleTest/SpawnTask.js @@ -300,9 +300,10 @@ var add_task = (function () { } } catch (ex) { try { - ok(false, "" + ex); + ok(false, "" + ex, "Should not throw any errors", ex.stack); } catch (ex2) { - ok(false, "(The exception cannot be converted to string.)"); + ok(false, "(The exception cannot be converted to string.)", + "Should not throw any errors", ex.stack); } } // All tasks are finished. From b420ecaa9586375c7d1f0d49bfea71f8b7b6002e Mon Sep 17 00:00:00 2001 From: Jan Odvarko Date: Wed, 9 Aug 2017 15:28:42 +0200 Subject: [PATCH 019/166] Bug 1388368 - Fix the Console panel in Launchpad; r=nchevobbe MozReview-Commit-ID: 4AAs8Mre3bt --HG-- extra : rebase_source : 2719f5231656625b4ba9f9b408d774d04d6ea1f0 --- devtools/client/webconsole/local-dev/index.js | 5 ++++- .../client/webconsole/local-dev/jsterm-stub.js | 6 ++++++ .../client/webconsole/local-dev/system-stub.js | 17 +++++++++++++++++ devtools/client/webconsole/package.json | 2 +- devtools/client/webconsole/webpack.config.js | 9 ++++++--- 5 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 devtools/client/webconsole/local-dev/system-stub.js diff --git a/devtools/client/webconsole/local-dev/index.js b/devtools/client/webconsole/local-dev/index.js index a23726b77e17..d2b84830adfb 100644 --- a/devtools/client/webconsole/local-dev/index.js +++ b/devtools/client/webconsole/local-dev/index.js @@ -21,7 +21,10 @@ try { EventEmitter.decorate(window); -require("../../themes/new-webconsole.css"); +require("../../themes/widgets.css"); +require("../../themes/webconsole.css"); +require("../../themes/components-frame.css"); +require("../../themes/light-theme.css"); require("../../shared/components/reps/reps.css"); pref("devtools.debugger.remote-timeout", 10000); diff --git a/devtools/client/webconsole/local-dev/jsterm-stub.js b/devtools/client/webconsole/local-dev/jsterm-stub.js index 2fb0f912a66a..422f090a9bf3 100644 --- a/devtools/client/webconsole/local-dev/jsterm-stub.js +++ b/devtools/client/webconsole/local-dev/jsterm-stub.js @@ -171,6 +171,12 @@ JSTerm.prototype = { return grip ? grip.actor : null; }, + + focus() { + if (this.inputNode) { + this.inputNode.focus(); + } + }, }; module.exports.JSTerm = JSTerm; diff --git a/devtools/client/webconsole/local-dev/system-stub.js b/devtools/client/webconsole/local-dev/system-stub.js new file mode 100644 index 000000000000..f4342a003706 --- /dev/null +++ b/devtools/client/webconsole/local-dev/system-stub.js @@ -0,0 +1,17 @@ +/* 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 strict"; + +var platform = ""; + +if (/Mac OS X/.test(window.navigator.userAgent)) { + platform = "macosx"; +} + +module.exports = { + constants: { + platform: platform + } +}; diff --git a/devtools/client/webconsole/package.json b/devtools/client/webconsole/package.json index 288cc05f7d84..dfdb3fa43a0e 100644 --- a/devtools/client/webconsole/package.json +++ b/devtools/client/webconsole/package.json @@ -16,7 +16,7 @@ "cross-env": "^3.1.3", "devtools-config": "0.0.12", "devtools-launchpad": "0.0.67", - "devtools-modules": "0.0.24", + "devtools-modules": "0.0.28", "enzyme": "^2.4.1", "expect": "^1.16.0", "file-loader": "^0.10.1", diff --git a/devtools/client/webconsole/webpack.config.js b/devtools/client/webconsole/webpack.config.js index 760c965143fb..91dffa400548 100644 --- a/devtools/client/webconsole/webpack.config.js +++ b/devtools/client/webconsole/webpack.config.js @@ -43,7 +43,7 @@ let webpackConfig = { webpackConfig.resolve = { alias: { - "Services": "devtools-modules/client/shared/shim/Services", + "Services": "devtools-modules/src/Services", "devtools/client/webconsole/jsterm": path.join(projectPath, "jsterm-stub"), "devtools/client/webconsole/utils": path.join(__dirname, "new-console-output/test/fixtures/WebConsoleUtils"), @@ -63,9 +63,10 @@ webpackConfig.resolve = { "devtools/shared/locales": path.join(__dirname, "../../shared/locales/en-US"), "devtools/shared/plural-form": path.join(__dirname, "../../shared/plural-form"), "devtools/shared/l10n": path.join(__dirname, "../../shared/l10n"), + "devtools/shared/system": path.join(projectPath, "system-stub"), "devtools/client/framework/devtools": path.join(__dirname, "../../client/shims/devtools"), - "devtools/client/framework/menu": "devtools-modules/client/framework/menu", + "devtools/client/framework/menu": "devtools-modules/src/menu", "devtools/client/framework/menu-item": path.join(__dirname, "../../client/framework/menu-item"), "devtools/client/shared/components/reps/reps": path.join(__dirname, "../../client/shared/components/reps/reps"), @@ -74,9 +75,11 @@ webpackConfig.resolve = { "devtools/client/shared/components/stack-trace": path.join(__dirname, "../../client/shared/components/stack-trace"), "devtools/client/shared/source-utils": path.join(__dirname, "../../client/shared/source-utils"), "devtools/client/shared/components/frame": path.join(__dirname, "../../client/shared/components/frame"), + "devtools/client/shared/key-shortcuts": "devtools-modules/src/key-shortcuts", + "devtools/client/shared/zoom-keys": "devtools-modules/src/zoom-keys", "devtools/shared/defer": path.join(__dirname, "../../shared/defer"), - "devtools/shared/event-emitter": "devtools-modules/shared/event-emitter", + "devtools/shared/event-emitter": "devtools-modules/src/utils/event-emitter", "devtools/shared/client/main": path.join(__dirname, "new-console-output/test/fixtures/ObjectClient"), "devtools/shared/platform/clipboard": path.join(__dirname, "../../shared/platform/content/clipboard"), } From a18f8263824e43064566d066714548834aa336d6 Mon Sep 17 00:00:00 2001 From: Cykesiopka Date: Tue, 8 Aug 2017 07:38:23 +0800 Subject: [PATCH 020/166] Bug 1387853 - Update Google roots in PreloadedHPKPins.json to fix periodic Static HPKP updates. r=keeler Some entries in the existing list referred to roots that were removed from in upstream NSS in Bug 1380941 (the equivalent change landed in Firefox's copy of NSS in Bug 1370890). This broke the periodic HPKP script because it would still try to find the roots within our built-in roots. Running dumpGoogleRoots.js and pasting the output into the appropriate section of PreloadedHPKPins.json fixes this. MozReview-Commit-ID: Ck6WobCk9gl --HG-- extra : rebase_source : 676e39c7e447f8e2db2cdb52bacaa57d20088a46 --- security/manager/tools/PreloadedHPKPins.json | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/security/manager/tools/PreloadedHPKPins.json b/security/manager/tools/PreloadedHPKPins.json index 672979c0268a..18e0ad8fd1c4 100644 --- a/security/manager/tools/PreloadedHPKPins.json +++ b/security/manager/tools/PreloadedHPKPins.json @@ -92,13 +92,14 @@ // they'd like us to be more liberal. For the initial list, we are using // the certs from http://pki.google.com/roots.pem. // We have no built-in for commented out CAs. + // This list should be updated via the dumpGoogleRoots.js script. { "name": "google_root_pems", "sha256_hashes": [ "AddTrust External Root", "AddTrust Low-Value Services Root", - "AddTrust Public Services Root", - "AddTrust Qualified Certificates Root", + // "AddTrust Public CA Root", + // "AddTrust Qualified CA Root", "AffirmTrust Commercial", "AffirmTrust Networking", "AffirmTrust Premium", @@ -108,8 +109,6 @@ "COMODO Certification Authority", "COMODO ECC Certification Authority", "COMODO RSA Certification Authority", - "Comodo Secure Services root", - "Comodo Trusted Services root", "Cybertrust Global Root", "DigiCert Assured ID Root CA", "DigiCert Assured ID Root G2", @@ -125,33 +124,42 @@ "Entrust.net Premium 2048 Secure Server CA", // "Equifax Secure Certificate Authority", "GeoTrust Global CA", - "GeoTrust Global CA 2", + // "GeoTrust Global CA 2", "GeoTrust Primary Certification Authority", "GeoTrust Primary Certification Authority - G2", "GeoTrust Primary Certification Authority - G3", "GeoTrust Universal CA", "GeoTrust Universal CA 2", + // "GlobalSign", "GlobalSign ECC Root CA - R4", "GlobalSign ECC Root CA - R5", "GlobalSign Root CA", "GlobalSign Root CA - R2", "GlobalSign Root CA - R3", + // "GlobalSign Root CA - R8", "Go Daddy Class 2 CA", "Go Daddy Root Certificate Authority - G2", + // "GTS Root R1", + // "GTS Root R2", + // "GTS Root R3", + // "GTS Root R4", + // "Secure Certificate Services", "Starfield Class 2 CA", "Starfield Root Certificate Authority - G2", "thawte Primary Root CA", "thawte Primary Root CA - G2", "thawte Primary Root CA - G3", + // "Trusted Certificate Services", "USERTrust ECC Certification Authority", "USERTrust RSA Certification Authority", - "UTN USERFirst Hardware Root CA", + // "UTN-USERFirst-Hardware", "Verisign Class 3 Public Primary Certification Authority - G3", "VeriSign Class 3 Public Primary Certification Authority - G4", "VeriSign Class 3 Public Primary Certification Authority - G5", "VeriSign Universal Root Certification Authority" ] } + // The list above should be updated via the dumpGoogleRoots.js script. ], "entries": [ From eccc7f0dd33341d71877b6854127e3483fcd9c52 Mon Sep 17 00:00:00 2001 From: Cykesiopka Date: Tue, 8 Aug 2017 00:44:02 +0800 Subject: [PATCH 021/166] Bug 1388088 - Fix incorrect Cu.import() URL to unbreak HSTS periodic updates. r=keeler The preload script currently imports XPCOMUtils.jsm like so: > Cu.import("resource:///modules/XPCOMUtils.jsm"); As explained in Bug 1383215 comments [21, 24], this has been incorrect for years, but happened to work. The import URL is changed so it points at the correct thing now: > Cu.import("resource://gre/modules/XPCOMUtils.jsm"); MozReview-Commit-ID: J6j594sJs60 --HG-- extra : rebase_source : 402808439e5fba8b4909dee9a96f1e44debfa6f0 --- security/manager/tools/getHSTSPreloadList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/manager/tools/getHSTSPreloadList.js b/security/manager/tools/getHSTSPreloadList.js index f68f64900054..976b6968aefa 100644 --- a/security/manager/tools/getHSTSPreloadList.js +++ b/security/manager/tools/getHSTSPreloadList.js @@ -19,7 +19,7 @@ var Cr = Components.results; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource:///modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); const SOURCE = "https://chromium.googlesource.com/chromium/src/net/+/master/http/transport_security_state_static.json?format=TEXT"; const OUTPUT = "nsSTSPreloadList.inc"; From dfe3f997a23fe64e120e485085a662712e831217 Mon Sep 17 00:00:00 2001 From: Masatoshi Kimura Date: Sun, 6 Aug 2017 23:34:32 +0900 Subject: [PATCH 022/166] Bug 1387832 - Remove @deprecated nsIAccessibleRetrieval. r=surkov MozReview-Commit-ID: DaqIezvQvUe --HG-- extra : rebase_source : e5449a0179b18ddcc45faff1f7e98bb22dbb61ae --- accessible/interfaces/nsIAccessibilityService.idl | 8 -------- accessible/xpcom/xpcAccessibilityService.cpp | 3 +-- accessible/xpcom/xpcAccessibilityService.h | 3 +-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/accessible/interfaces/nsIAccessibilityService.idl b/accessible/interfaces/nsIAccessibilityService.idl index c073eaebf134..11e461e5d0cb 100644 --- a/accessible/interfaces/nsIAccessibilityService.idl +++ b/accessible/interfaces/nsIAccessibilityService.idl @@ -98,11 +98,3 @@ interface nsIAccessibilityService : nsISupports */ boolean isLogged(in AString aModule); }; - -/** - * @deprecated, use nsIAccessibilityService instead. - */ -[scriptable, builtinclass, uuid(d85e0cbe-47ce-490c-8488-f821dd2be0c2)] -interface nsIAccessibleRetrieval : nsIAccessibilityService -{ -}; diff --git a/accessible/xpcom/xpcAccessibilityService.cpp b/accessible/xpcom/xpcAccessibilityService.cpp index 49c5e1082501..e0e786e24043 100644 --- a/accessible/xpcom/xpcAccessibilityService.cpp +++ b/accessible/xpcom/xpcAccessibilityService.cpp @@ -91,8 +91,7 @@ xpcAccessibilityService::Release(void) return count; } -NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService, - nsIAccessibleRetrieval) +NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService) NS_IMETHODIMP xpcAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication) diff --git a/accessible/xpcom/xpcAccessibilityService.h b/accessible/xpcom/xpcAccessibilityService.h index 76389a8a5d05..05e80ab5610c 100644 --- a/accessible/xpcom/xpcAccessibilityService.h +++ b/accessible/xpcom/xpcAccessibilityService.h @@ -7,13 +7,12 @@ #include "nsIAccessibilityService.h" -class xpcAccessibilityService : public nsIAccessibleRetrieval +class xpcAccessibilityService : public nsIAccessibilityService { public: NS_DECL_ISUPPORTS NS_DECL_NSIACCESSIBILITYSERVICE - NS_DECL_NSIACCESSIBLERETRIEVAL /** * Return true if xpc accessibility service is in use. From 8dbb8d014f3b3670d0496480075a09f049ceb6b8 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 9 Aug 2017 17:22:51 +0200 Subject: [PATCH 023/166] Backed out changeset d2e76a2d8794 (bug 1388368) for eslint failures in system-stub.js (should be Unix linebreaks, not the Windows' ones). r=backout --- devtools/client/webconsole/local-dev/index.js | 5 +---- .../client/webconsole/local-dev/jsterm-stub.js | 6 ------ .../client/webconsole/local-dev/system-stub.js | 17 ----------------- devtools/client/webconsole/package.json | 2 +- devtools/client/webconsole/webpack.config.js | 9 +++------ 5 files changed, 5 insertions(+), 34 deletions(-) delete mode 100644 devtools/client/webconsole/local-dev/system-stub.js diff --git a/devtools/client/webconsole/local-dev/index.js b/devtools/client/webconsole/local-dev/index.js index d2b84830adfb..a23726b77e17 100644 --- a/devtools/client/webconsole/local-dev/index.js +++ b/devtools/client/webconsole/local-dev/index.js @@ -21,10 +21,7 @@ try { EventEmitter.decorate(window); -require("../../themes/widgets.css"); -require("../../themes/webconsole.css"); -require("../../themes/components-frame.css"); -require("../../themes/light-theme.css"); +require("../../themes/new-webconsole.css"); require("../../shared/components/reps/reps.css"); pref("devtools.debugger.remote-timeout", 10000); diff --git a/devtools/client/webconsole/local-dev/jsterm-stub.js b/devtools/client/webconsole/local-dev/jsterm-stub.js index 422f090a9bf3..2fb0f912a66a 100644 --- a/devtools/client/webconsole/local-dev/jsterm-stub.js +++ b/devtools/client/webconsole/local-dev/jsterm-stub.js @@ -171,12 +171,6 @@ JSTerm.prototype = { return grip ? grip.actor : null; }, - - focus() { - if (this.inputNode) { - this.inputNode.focus(); - } - }, }; module.exports.JSTerm = JSTerm; diff --git a/devtools/client/webconsole/local-dev/system-stub.js b/devtools/client/webconsole/local-dev/system-stub.js deleted file mode 100644 index f4342a003706..000000000000 --- a/devtools/client/webconsole/local-dev/system-stub.js +++ /dev/null @@ -1,17 +0,0 @@ -/* 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 strict"; - -var platform = ""; - -if (/Mac OS X/.test(window.navigator.userAgent)) { - platform = "macosx"; -} - -module.exports = { - constants: { - platform: platform - } -}; diff --git a/devtools/client/webconsole/package.json b/devtools/client/webconsole/package.json index dfdb3fa43a0e..288cc05f7d84 100644 --- a/devtools/client/webconsole/package.json +++ b/devtools/client/webconsole/package.json @@ -16,7 +16,7 @@ "cross-env": "^3.1.3", "devtools-config": "0.0.12", "devtools-launchpad": "0.0.67", - "devtools-modules": "0.0.28", + "devtools-modules": "0.0.24", "enzyme": "^2.4.1", "expect": "^1.16.0", "file-loader": "^0.10.1", diff --git a/devtools/client/webconsole/webpack.config.js b/devtools/client/webconsole/webpack.config.js index 91dffa400548..760c965143fb 100644 --- a/devtools/client/webconsole/webpack.config.js +++ b/devtools/client/webconsole/webpack.config.js @@ -43,7 +43,7 @@ let webpackConfig = { webpackConfig.resolve = { alias: { - "Services": "devtools-modules/src/Services", + "Services": "devtools-modules/client/shared/shim/Services", "devtools/client/webconsole/jsterm": path.join(projectPath, "jsterm-stub"), "devtools/client/webconsole/utils": path.join(__dirname, "new-console-output/test/fixtures/WebConsoleUtils"), @@ -63,10 +63,9 @@ webpackConfig.resolve = { "devtools/shared/locales": path.join(__dirname, "../../shared/locales/en-US"), "devtools/shared/plural-form": path.join(__dirname, "../../shared/plural-form"), "devtools/shared/l10n": path.join(__dirname, "../../shared/l10n"), - "devtools/shared/system": path.join(projectPath, "system-stub"), "devtools/client/framework/devtools": path.join(__dirname, "../../client/shims/devtools"), - "devtools/client/framework/menu": "devtools-modules/src/menu", + "devtools/client/framework/menu": "devtools-modules/client/framework/menu", "devtools/client/framework/menu-item": path.join(__dirname, "../../client/framework/menu-item"), "devtools/client/shared/components/reps/reps": path.join(__dirname, "../../client/shared/components/reps/reps"), @@ -75,11 +74,9 @@ webpackConfig.resolve = { "devtools/client/shared/components/stack-trace": path.join(__dirname, "../../client/shared/components/stack-trace"), "devtools/client/shared/source-utils": path.join(__dirname, "../../client/shared/source-utils"), "devtools/client/shared/components/frame": path.join(__dirname, "../../client/shared/components/frame"), - "devtools/client/shared/key-shortcuts": "devtools-modules/src/key-shortcuts", - "devtools/client/shared/zoom-keys": "devtools-modules/src/zoom-keys", "devtools/shared/defer": path.join(__dirname, "../../shared/defer"), - "devtools/shared/event-emitter": "devtools-modules/src/utils/event-emitter", + "devtools/shared/event-emitter": "devtools-modules/shared/event-emitter", "devtools/shared/client/main": path.join(__dirname, "new-console-output/test/fixtures/ObjectClient"), "devtools/shared/platform/clipboard": path.join(__dirname, "../../shared/platform/content/clipboard"), } From 8c0505cc7c248c4841dcc5e37204292cfdb9e23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Tue, 8 Aug 2017 22:01:53 +0200 Subject: [PATCH 024/166] Bug 1387456 - Remove the first tab's start border when the window is maximized/fullscreen. r=johannh MozReview-Commit-ID: 6lEYzheWNtX --HG-- extra : rebase_source : 486e9740ea863a0f72c260875885d41495deef14 --- browser/base/content/tabbrowser.xml | 2 ++ browser/themes/shared/tabs.inc.css | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index d0e1dd12c389..c1eb36c8b959 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -5958,6 +5958,8 @@ Services.prefs.addObserver("privacy.userContext", this); this.observe(null, "nsPref:changed", "privacy.userContext.enabled"); + + this._setPositionalAttributes(); ]]> diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index b36212f65453..de83e90cbb6e 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -312,6 +312,10 @@ background-repeat: repeat-x; } +:root:not([sizemode=normal]) .tabbrowser-tab[first-visible-tab] > .tab-stack > .tab-background[selected=true] { + border-inline-start-style: none; +} + .tab-line[selected=true] { background-color: Highlight; } From 98ce69f791bebca795053b2c385ff4029c41bcab Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Wed, 9 Aug 2017 11:24:49 -0400 Subject: [PATCH 025/166] Bug 1388342 - Ensure browser_tabstrip_overflow_underflow_reflows.js works for both the e10s and non-e10s case. r=florian We hit the _adjustFocusAfterTabSwitch function in both the e10s and non-e10s cases, but through different code paths. This makes the expected stack less specific to account for both cases. MozReview-Commit-ID: AI4KLUNjUqZ --HG-- extra : rebase_source : b1fd2df5231e406fe33b7cb4f778c7dc5797b08c --- .../browser_tabstrip_overflow_underflow_reflows.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/browser/base/content/test/performance/browser_tabstrip_overflow_underflow_reflows.js b/browser/base/content/test/performance/browser_tabstrip_overflow_underflow_reflows.js index 2f041d9c1749..135dd4ba5789 100644 --- a/browser/base/content/test/performance/browser_tabstrip_overflow_underflow_reflows.js +++ b/browser/base/content/test/performance/browser_tabstrip_overflow_underflow_reflows.js @@ -15,17 +15,6 @@ const EXPECTED_OVERFLOW_REFLOWS = [ "select@chrome://global/content/bindings/textbox.xml", "focusAndSelectUrlBar@chrome://browser/content/browser.js", "_adjustFocusAfterTabSwitch@chrome://browser/content/tabbrowser.xml", - "updateDisplay/<@chrome://browser/content/tabbrowser.xml", - "set_selectedIndex@chrome://browser/content/tabbrowser.xml", - "set_selectedPanel@chrome://global/content/bindings/tabbox.xml", - "set_selectedIndex@chrome://global/content/bindings/tabbox.xml", - "set_selectedItem@chrome://global/content/bindings/tabbox.xml", - "set_selectedTab@chrome://global/content/bindings/tabbox.xml", - "set_selectedTab@chrome://browser/content/tabbrowser.xml", - "loadOneTab@chrome://browser/content/tabbrowser.xml", - "openLinkIn@chrome://browser/content/utilityOverlay.js", - "openUILinkIn@chrome://browser/content/utilityOverlay.js", - "BrowserOpenTab@chrome://browser/content/browser.js", ] }, ]; From 0132ad567f1c8f79193a7736148abe8b8289a0e2 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 7 Aug 2017 10:09:32 -0400 Subject: [PATCH 026/166] Bug 1386363 - remove access to the com.apple.SystemConfiguration.configd mach service from content processes; r=haik MozReview-Commit-ID: 3hFEx67JkdO --HG-- extra : rebase_source : f3671c7d7682aeb5ff4b89d2409670fcadc2341a --- security/sandbox/mac/SandboxPolicies.h | 1 - 1 file changed, 1 deletion(-) diff --git a/security/sandbox/mac/SandboxPolicies.h b/security/sandbox/mac/SandboxPolicies.h index 1dd6669f9443..988f45c2ea29 100644 --- a/security/sandbox/mac/SandboxPolicies.h +++ b/security/sandbox/mac/SandboxPolicies.h @@ -187,7 +187,6 @@ static const char contentSandboxRules[] = R"( (global-name "com.apple.pasteboard.1") (global-name "com.apple.audio.coreaudiod") (global-name "com.apple.audio.audiohald") - (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.iconservices")) ; bug 1376163 From f601c0f998ac069c55dab3300cf00c70e4c4d1e6 Mon Sep 17 00:00:00 2001 From: Kirk Steuber Date: Tue, 8 Aug 2017 14:59:49 -0700 Subject: [PATCH 027/166] Bug 1376511 - Handle Browser:Thumbnail:CheckState during idle period r=mconley MozReview-Commit-ID: 6n4nzCqTt0O --HG-- extra : rebase_source : 4b1d0bd8a662311fbf24844f091d8413a88c159c --- toolkit/content/browser-child.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 50880cfd0ea6..5893b253d310 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -559,9 +559,11 @@ addMessageListener("Browser:Thumbnail:Request", function(aMessage) { * Remote isSafeForCapture request handler for PageThumbs. */ addMessageListener("Browser:Thumbnail:CheckState", function(aMessage) { - let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); - sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { - result + requestIdleCallback(() => { + let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); + sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { + result + }); }); }); From 132c433aab557cda9daa594c90a92cc66ef18f8a Mon Sep 17 00:00:00 2001 From: Bob Owen Date: Mon, 7 Aug 2017 17:27:10 +0100 Subject: [PATCH 028/166] Bug 1388048 - Check for failure of ResolveJunctionPointsAndSymLinks in GeckoChildProcessHost::GetPathToBinary. r=jimm This patch also adds logging into ResolveJunctionPointsAndSymLinks to help diagnose issues that might arise if the resolution fails or the path is not usable for some reason. --- ipc/glue/GeckoChildProcessHost.cpp | 10 +++++++--- widget/windows/WinUtils.cpp | 9 +++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 2d6358480b9b..00b3b27ae8f8 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -147,14 +147,18 @@ GeckoChildProcessHost::GetPathToBinary(FilePath& exePath, GeckoProcessType proce if (!::GetModuleFileNameW(nullptr, exePathBuf, MAXPATHLEN)) { MOZ_CRASH("GetModuleFileNameW failed (FIXME)"); } - std::wstring exePathStr = exePathBuf; #if defined(MOZ_SANDBOX) // We need to start the child process using the real path, so that the // sandbox policy rules will match for DLLs loaded from the bin dir after // we have lowered the sandbox. - widget::WinUtils::ResolveJunctionPointsAndSymLinks(exePathStr); + std::wstring exePathStr = exePathBuf; + if (widget::WinUtils::ResolveJunctionPointsAndSymLinks(exePathStr)) { + exePath = FilePath::FromWStringHack(exePathStr); + } else #endif - exePath = FilePath::FromWStringHack(exePathStr); + { + exePath = FilePath::FromWStringHack(exePathBuf); + } #elif defined(OS_POSIX) exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]); #else diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp index 61cfb87ed9ca..cecbc8eda76c 100644 --- a/widget/windows/WinUtils.cpp +++ b/widget/windows/WinUtils.cpp @@ -62,6 +62,9 @@ mozilla::LazyLogModule gWindowsLog("Widget"); +#define LOG_E(...) MOZ_LOG(gWindowsLog, LogLevel::Error, (__VA_ARGS__)) +#define LOG_D(...) MOZ_LOG(gWindowsLog, LogLevel::Debug, (__VA_ARGS__)) + using namespace mozilla::gfx; namespace mozilla { @@ -1837,6 +1840,8 @@ WinUtils::GetMaxTouchPoints() bool WinUtils::ResolveJunctionPointsAndSymLinks(std::wstring& aPath) { + LOG_D("ResolveJunctionPointsAndSymLinks: Resolving path: %S", aPath.c_str()); + wchar_t path[MAX_PATH] = { 0 }; nsAutoHandle handle( @@ -1849,12 +1854,15 @@ WinUtils::ResolveJunctionPointsAndSymLinks(std::wstring& aPath) nullptr)); if (handle == INVALID_HANDLE_VALUE) { + LOG_E("Failed to open file handle to resolve path. GetLastError=%d", + GetLastError()); return false; } DWORD pathLen = GetFinalPathNameByHandleW( handle, path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); if (pathLen == 0 || pathLen >= MAX_PATH) { + LOG_E("GetFinalPathNameByHandleW failed. GetLastError=%d", GetLastError()); return false; } aPath = path; @@ -1868,6 +1876,7 @@ WinUtils::ResolveJunctionPointsAndSymLinks(std::wstring& aPath) aPath.erase(0, 4); } + LOG_D("ResolveJunctionPointsAndSymLinks: Resolved path to: %S", aPath.c_str()); return true; } From 8783a1affdbaccd4cd47a82cf42e341ebe8e709d Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:07:11 -0400 Subject: [PATCH 029/166] Bug 1385003 - Use PlainOldDataSerializer for WR struct serialization to avoid getting them out of sync. r=jrmuizel MozReview-Commit-ID: 6x3G0Ik6PJj --HG-- extra : rebase_source : ed22985d0944d0c023467fb6339113ba09a58038 --- gfx/layers/wr/WebRenderMessageUtils.h | 142 ++------------------------ 1 file changed, 10 insertions(+), 132 deletions(-) diff --git a/gfx/layers/wr/WebRenderMessageUtils.h b/gfx/layers/wr/WebRenderMessageUtils.h index e9eeffeea32b..bc02b0b1748c 100644 --- a/gfx/layers/wr/WebRenderMessageUtils.h +++ b/gfx/layers/wr/WebRenderMessageUtils.h @@ -37,88 +37,32 @@ struct ParamTraits template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::IdNamespace& aParam) - { - WriteParam(aMsg, aParam.mHandle); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::IdNamespace* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mHandle); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::ImageKey& aParam) - { - WriteParam(aMsg, aParam.mNamespace); - WriteParam(aMsg, aParam.mHandle); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::ImageKey* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mNamespace) - && ReadParam(aMsg, aIter, &aResult->mHandle); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::FontKey& aParam) - { - WriteParam(aMsg, aParam.mNamespace); - WriteParam(aMsg, aParam.mHandle); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::FontKey* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mNamespace) - && ReadParam(aMsg, aIter, &aResult->mHandle); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::ExternalImageId& aParam) - { - WriteParam(aMsg, aParam.mHandle); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::ExternalImageId* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mHandle); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::PipelineId& aParam) - { - WriteParam(aMsg, aParam.mNamespace); - WriteParam(aMsg, aParam.mHandle); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::PipelineId* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mNamespace) - && ReadParam(aMsg, aIter, &aResult->mHandle); - } }; template<> @@ -132,80 +76,26 @@ struct ParamTraits template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::LayoutSize& aParam) - { - WriteParam(aMsg, aParam.width); - WriteParam(aMsg, aParam.height); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::LayoutSize* aResult) - { - return ReadParam(aMsg, aIter, &aResult->width) - && ReadParam(aMsg, aIter, &aResult->height); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::LayoutRect& aParam) - { - WriteParam(aMsg, aParam.origin.x); - WriteParam(aMsg, aParam.origin.y); - WriteParam(aMsg, aParam.size.width); - WriteParam(aMsg, aParam.size.height); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::LayoutRect* aResult) - { - return ReadParam(aMsg, aIter, &aResult->origin.x) - && ReadParam(aMsg, aIter, &aResult->origin.y) - && ReadParam(aMsg, aIter, &aResult->size.width) - && ReadParam(aMsg, aIter, &aResult->size.height); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::LayoutPoint& aParam) - { - WriteParam(aMsg, aParam.x); - WriteParam(aMsg, aParam.y); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::LayoutPoint* aResult) - { - return ReadParam(aMsg, aIter, &aResult->x) && - ReadParam(aMsg, aIter, &aResult->y); - } }; template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::WrImageMask& aParam) - { - WriteParam(aMsg, aParam.image); - WriteParam(aMsg, aParam.rect); - WriteParam(aMsg, aParam.repeat); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::WrImageMask* aResult) - { - return ReadParam(aMsg, aIter, &aResult->image) - && ReadParam(aMsg, aIter, &aResult->rect) - && ReadParam(aMsg, aIter, &aResult->repeat); - } }; template<> @@ -228,20 +118,8 @@ struct ParamTraits template<> struct ParamTraits + : public PlainOldDataSerializer { - static void - Write(Message* aMsg, const mozilla::wr::BuiltDisplayListDescriptor& aParam) - { - WriteParam(aMsg, aParam.builder_start_time); - WriteParam(aMsg, aParam.builder_finish_time); - } - - static bool - Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::BuiltDisplayListDescriptor* aResult) - { - return ReadParam(aMsg, aIter, &aResult->builder_start_time) - && ReadParam(aMsg, aIter, &aResult->builder_finish_time); - } }; } // namespace IPC From b43eb147e02b5a9092f64e1eb30518e0b920b1c5 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:18 -0400 Subject: [PATCH 030/166] Bug 1385003 - Update webrender to commit e68c8acb021656440d26ac46e705e7ceb31891e6. r=jrmuizel MozReview-Commit-ID: Kw49PJqoLn4 --HG-- extra : rebase_source : 9d7dc062bde4eaffa94bc8d14043ee267afd256a --- gfx/doc/README.webrender | 2 +- gfx/webrender/Cargo.toml | 4 +- gfx/webrender/build.rs | 8 +- gfx/webrender/examples/animation.rs | 8 +- gfx/webrender/examples/basic.rs | 24 +- gfx/webrender/examples/blob.rs | 10 +- gfx/webrender/examples/common/boilerplate.rs | 45 +- gfx/webrender/examples/iframe.rs | 74 ++ gfx/webrender/examples/nested_display_list.rs | 12 +- gfx/webrender/examples/scrolling.rs | 10 +- gfx/webrender/examples/yuv.rs | 21 +- gfx/webrender/res/cs_text_run.vs.glsl | 5 +- gfx/webrender/res/prim_shared.glsl | 25 +- gfx/webrender/res/ps_border_edge.vs.glsl | 29 +- gfx/webrender/res/ps_text_run.vs.glsl | 23 +- gfx/webrender/src/clip_scroll_tree.rs | 26 +- gfx/webrender/src/debug_render.rs | 93 +- gfx/webrender/src/device.rs | 484 ++++----- gfx/webrender/src/frame.rs | 79 +- gfx/webrender/src/frame_builder.rs | 34 +- gfx/webrender/src/glyph_cache.rs | 104 ++ gfx/webrender/src/glyph_rasterizer.rs | 93 +- gfx/webrender/src/internal_types.rs | 98 +- gfx/webrender/src/lib.rs | 73 +- gfx/webrender/src/platform/macos/font.rs | 26 +- gfx/webrender/src/platform/unix/font.rs | 275 ++++-- gfx/webrender/src/platform/windows/font.rs | 10 +- gfx/webrender/src/prim_store.rs | 85 +- gfx/webrender/src/profiler.rs | 19 + gfx/webrender/src/record.rs | 18 +- gfx/webrender/src/render_backend.rs | 927 ++++++++++-------- gfx/webrender/src/render_task.rs | 2 +- gfx/webrender/src/renderer.rs | 482 +++++---- gfx/webrender/src/resource_cache.rs | 567 +++++------ gfx/webrender/src/scene.rs | 20 +- gfx/webrender/src/texture_cache.rs | 41 +- gfx/webrender/src/tiling.rs | 34 +- gfx/webrender_api/Cargo.toml | 1 + gfx/webrender_api/src/api.rs | 584 ++++++----- gfx/webrender_api/src/color.rs | 22 + gfx/webrender_api/src/display_item.rs | 1 + gfx/webrender_api/src/display_list.rs | 131 ++- gfx/webrender_api/src/font.rs | 62 +- gfx/webrender_api/src/lib.rs | 6 + 44 files changed, 2664 insertions(+), 2033 deletions(-) create mode 100644 gfx/webrender/examples/iframe.rs create mode 100644 gfx/webrender/src/glyph_cache.rs diff --git a/gfx/doc/README.webrender b/gfx/doc/README.webrender index 7ef0fac3d3b5..4bebd46e47bb 100644 --- a/gfx/doc/README.webrender +++ b/gfx/doc/README.webrender @@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc the need to run the cargo update command in js/src as well. Hopefully this will be resolved soon. -Latest Commit: 0748e02d1be5f889fc17de2eb81c0c363ee3aa80 +Latest Commit: e68c8acb021656440d26ac46e705e7ceb31891e6 diff --git a/gfx/webrender/Cargo.toml b/gfx/webrender/Cargo.toml index 6d284f9acee8..3a2422c00860 100644 --- a/gfx/webrender/Cargo.toml +++ b/gfx/webrender/Cargo.toml @@ -18,7 +18,7 @@ bincode = "0.8" bit-set = "0.4" byteorder = "1.0" euclid = "0.15.1" -fnv = "1.0" +fxhash = "0.2.1" gleam = "0.4.7" lazy_static = "0.2" log = "0.3" @@ -38,7 +38,7 @@ rand = "0.3" # for the benchmarks servo-glutin = "0.11" # for the example apps [target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies] -freetype = { version = "0.2", default-features = false } +freetype = { version = "0.3", default-features = false } [target.'cfg(target_os = "windows")'.dependencies] dwrote = "0.4" diff --git a/gfx/webrender/build.rs b/gfx/webrender/build.rs index 699db398f27c..5f31d5121ab3 100644 --- a/gfx/webrender/build.rs +++ b/gfx/webrender/build.rs @@ -14,7 +14,7 @@ fn write_shaders(glsl_files: Vec, shader_file_path: &Path) { write!(shader_file, "use std::collections::HashMap;\n").unwrap(); write!(shader_file, "lazy_static! {{\n").unwrap(); write!(shader_file, " pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n").unwrap(); - write!(shader_file, " let mut h = HashMap::with_capacity({});\n", glsl_files.len()).unwrap(); + write!(shader_file, " let mut h = HashMap::new();\n").unwrap(); for glsl in glsl_files { let shader_name = glsl.file_name().unwrap().to_str().unwrap(); // strip .glsl @@ -27,9 +27,9 @@ fn write_shaders(glsl_files: Vec, shader_file_path: &Path) { write!(shader_file, " h.insert(\"{}\", include_str!(\"{}\"));\n", shader_name, full_name).unwrap(); } - write!(shader_file, " h\n").unwrap(); - write!(shader_file, " }};\n").unwrap(); - write!(shader_file, "}}\n").unwrap(); + write!(shader_file, " h\n").unwrap(); + write!(shader_file, " }};\n").unwrap(); + write!(shader_file, "}}\n").unwrap(); } fn main() { diff --git a/gfx/webrender/examples/animation.rs b/gfx/webrender/examples/animation.rs index 77b0b8936886..974ba2413539 100644 --- a/gfx/webrender/examples/animation.rs +++ b/gfx/webrender/examples/animation.rs @@ -20,7 +20,9 @@ use webrender::api::*; // around by using the arrow keys. It does this by using the animation API. fn body(_api: &RenderApi, + _document_id: &DocumentId, builder: &mut DisplayListBuilder, + _resouces: &mut ResourceUpdates, _pipeline_id: &PipelineId, _layout_size: &LayoutSize) { // Create a 100x100 stacking context with an animatable transform property. @@ -45,9 +47,7 @@ lazy_static! { static ref TRANSFORM: Mutex = Mutex::new(LayoutTransform::identity()); } -fn event_handler(event: &glutin::Event, - api: &RenderApi) -{ +fn event_handler(event: &glutin::Event, document_id: DocumentId, api: &RenderApi) { match *event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { @@ -61,7 +61,7 @@ fn event_handler(event: &glutin::Event, // webrender using the generate_frame API. This will recomposite with // the updated transform. let new_transform = TRANSFORM.lock().unwrap().post_translate(LayoutVector3D::new(offset.0, offset.1, 0.0)); - api.generate_frame(Some(DynamicProperties { + api.generate_frame(document_id, Some(DynamicProperties { transforms: vec![ PropertyValue { key: PropertyBindingKey::new(42), diff --git a/gfx/webrender/examples/basic.rs b/gfx/webrender/examples/basic.rs index 88c093c2a98c..f3cfa9d5f4b0 100644 --- a/gfx/webrender/examples/basic.rs +++ b/gfx/webrender/examples/basic.rs @@ -174,7 +174,9 @@ fn main() { } fn body(api: &RenderApi, + _document_id: &DocumentId, builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, _pipeline_id: &PipelineId, layout_size: &LayoutSize) { let bounds = LayoutRect::new(LayoutPoint::zero(), *layout_size); @@ -187,10 +189,12 @@ fn body(api: &RenderApi, Vec::new()); let image_mask_key = api.generate_image_key(); - api.add_image(image_mask_key, - ImageDescriptor::new(2, 2, ImageFormat::A8, true), - ImageData::new(vec![0, 80, 180, 255]), - None); + resources.add_image( + image_mask_key, + ImageDescriptor::new(2, 2, ImageFormat::A8, true), + ImageData::new(vec![0, 80, 180, 255]), + None + ); let mask = ImageMask { image: image_mask_key, rect: (75, 75).by(100, 100), @@ -230,7 +234,7 @@ fn body(api: &RenderApi, if false { // draw text? let font_key = api.generate_font_key(); let font_bytes = load_file("res/FreeSans.ttf"); - api.add_raw_font(font_key, font_bytes, 0); + resources.add_raw_font(font_key, font_bytes, 0); let text_bounds = (100, 200).by(700, 300); let glyphs = vec![ @@ -322,17 +326,17 @@ lazy_static! { static ref TOUCH_STATE: Mutex = Mutex::new(TouchState::new()); } -fn event_handler(event: &glutin::Event, api: &RenderApi) { +fn event_handler(event: &glutin::Event, document_id: DocumentId, api: &RenderApi) { match *event { glutin::Event::Touch(touch) => { match TOUCH_STATE.lock().unwrap().handle_event(touch) { TouchResult::Pan(pan) => { - api.set_pan(pan); - api.generate_frame(None); + api.set_pan(document_id, pan); + api.generate_frame(document_id, None); } TouchResult::Zoom(zoom) => { - api.set_pinch_zoom(ZoomFactor::new(zoom)); - api.generate_frame(None); + api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); + api.generate_frame(document_id, None); } TouchResult::None => {} } diff --git a/gfx/webrender/examples/blob.rs b/gfx/webrender/examples/blob.rs index de1fde1d0ab1..6d160dbeed74 100644 --- a/gfx/webrender/examples/blob.rs +++ b/gfx/webrender/examples/blob.rs @@ -213,11 +213,13 @@ impl api::BlobImageRenderer for CheckerboardRenderer { } fn body(api: &api::RenderApi, + _document_id: &api::DocumentId, builder: &mut api::DisplayListBuilder, + resources: &mut api::ResourceUpdates, _pipeline_id: &api::PipelineId, layout_size: &api::LayoutSize) { let blob_img1 = api.generate_image_key(); - api.add_image( + resources.add_image( blob_img1, api::ImageDescriptor::new(500, 500, api::ImageFormat::BGRA8, true), api::ImageData::new_blob_image(serialize_blob(api::ColorU::new(50, 50, 150, 255))), @@ -225,7 +227,7 @@ fn body(api: &api::RenderApi, ); let blob_img2 = api.generate_image_key(); - api.add_image( + resources.add_image( blob_img2, api::ImageDescriptor::new(200, 200, api::ImageFormat::BGRA8, true), api::ImageData::new_blob_image(serialize_blob(api::ColorU::new(50, 150, 50, 255))), @@ -262,9 +264,7 @@ fn body(api: &api::RenderApi, builder.pop_stacking_context(); } -fn event_handler(_event: &glutin::Event, - _api: &api::RenderApi) -{ +fn event_handler(_event: &glutin::Event, _document_id: api::DocumentId, _api: &api::RenderApi) { } fn main() { diff --git a/gfx/webrender/examples/common/boilerplate.rs b/gfx/webrender/examples/common/boilerplate.rs index 69e3a04826c4..8984530290f1 100644 --- a/gfx/webrender/examples/common/boilerplate.rs +++ b/gfx/webrender/examples/common/boilerplate.rs @@ -8,6 +8,7 @@ use std::env; use std::path::PathBuf; use webrender; use webrender::api::*; +use webrender::renderer::{PROFILER_DBG, RENDER_TARGET_DBG, TEXTURE_CACHE_DBG}; struct Notifier { window_proxy: glutin::WindowProxy, @@ -52,10 +53,13 @@ impl HandyDandyRectBuilder for (i32, i32) { } pub fn main_wrapper(builder_callback: fn(&RenderApi, + &DocumentId, &mut DisplayListBuilder, + &mut ResourceUpdates, &PipelineId, &LayoutSize) -> (), event_handler: fn(&glutin::Event, + DocumentId, &RenderApi) -> (), options: Option) { @@ -99,8 +103,9 @@ pub fn main_wrapper(builder_callback: fn(&RenderApi, }; let size = DeviceUintSize::new(width, height); - let (mut renderer, sender) = webrender::renderer::Renderer::new(gl, opts, size).unwrap(); + let (mut renderer, sender) = webrender::renderer::Renderer::new(gl, opts).unwrap(); let api = sender.create_api(); + let document_id = api.add_document(size); let notifier = Box::new(Notifier::new(window.create_window_proxy())); renderer.set_render_notifier(notifier); @@ -111,17 +116,21 @@ pub fn main_wrapper(builder_callback: fn(&RenderApi, let pipeline_id = PipelineId(0, 0); let layout_size = LayoutSize::new(width as f32, height as f32); let mut builder = DisplayListBuilder::new(pipeline_id, layout_size); + let mut resources = ResourceUpdates::new(); - builder_callback(&api, &mut builder, &pipeline_id, &layout_size); + builder_callback(&api, &document_id, &mut builder, &mut resources, &pipeline_id, &layout_size); api.set_display_list( - Some(root_background_color), + document_id, epoch, + Some(root_background_color), LayoutSize::new(width as f32, height as f32), builder.finalize(), - true); - api.set_root_pipeline(pipeline_id); - api.generate_frame(None); + true, + resources + ); + api.set_root_pipeline(document_id, pipeline_id); + api.generate_frame(document_id, None); 'outer: for event in window.wait_events() { let mut events = Vec::new(); @@ -139,12 +148,24 @@ pub fn main_wrapper(builder_callback: fn(&RenderApi, glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::P)) => { - let enable_profiler = !renderer.get_profiler_enabled(); - renderer.set_profiler_enabled(enable_profiler); - api.generate_frame(None); - } + let mut flags = renderer.get_debug_flags(); + flags.toggle(PROFILER_DBG); + renderer.set_debug_flags(flags); + }, + glutin::Event::KeyboardInput(glutin::ElementState::Pressed, + _, Some(glutin::VirtualKeyCode::O)) => { + let mut flags = renderer.get_debug_flags(); + flags.toggle(RENDER_TARGET_DBG); + renderer.set_debug_flags(flags); + }, + glutin::Event::KeyboardInput(glutin::ElementState::Pressed, + _, Some(glutin::VirtualKeyCode::I)) => { + let mut flags = renderer.get_debug_flags(); + flags.toggle(TEXTURE_CACHE_DBG); + renderer.set_debug_flags(flags); + }, - _ => event_handler(&event, &api), + _ => event_handler(&event, document_id, &api), } } @@ -152,4 +173,6 @@ pub fn main_wrapper(builder_callback: fn(&RenderApi, renderer.render(DeviceUintSize::new(width, height)); window.swap_buffers().ok(); } + + renderer.deinit(); } diff --git a/gfx/webrender/examples/iframe.rs b/gfx/webrender/examples/iframe.rs new file mode 100644 index 000000000000..f2902d8c25f3 --- /dev/null +++ b/gfx/webrender/examples/iframe.rs @@ -0,0 +1,74 @@ +/* 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/. */ + +extern crate gleam; +extern crate glutin; +extern crate webrender; + +#[path="common/boilerplate.rs"] +mod boilerplate; + +use boilerplate::HandyDandyRectBuilder; +use webrender::api::*; + +// This example uses the push_iframe API to nest a second pipeline's displaylist +// inside the root pipeline's display list. When it works, a green square is +// shown. If it fails, a red square is shown. + +fn body(api: &RenderApi, + document_id: &DocumentId, + builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, + pipeline_id: &PipelineId, + _layout_size: &LayoutSize) { + + // All the sub_* things are for the nested pipeline + let sub_size = DeviceUintSize::new(100, 100); + let sub_bounds = (0,0).to(sub_size.width as i32, sub_size.height as i32); + + let sub_pipeline_id = PipelineId(pipeline_id.0, 42); + let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size); + + sub_builder.push_stacking_context(ScrollPolicy::Scrollable, + sub_bounds, + None, + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new()); + // green rect visible == success + sub_builder.push_rect(sub_bounds, None, ColorF::new(0.0, 1.0, 0.0, 1.0)); + sub_builder.pop_stacking_context(); + + api.set_display_list( + *document_id, + Epoch(0), + None, + sub_bounds.size, + sub_builder.finalize(), + true, + ResourceUpdates::new(), + ); + + let bounds = sub_bounds; + // And this is for the root pipeline + builder.push_stacking_context(ScrollPolicy::Scrollable, + bounds, + Some(PropertyBinding::Binding(PropertyBindingKey::new(42))), + TransformStyle::Flat, + None, + MixBlendMode::Normal, + Vec::new()); + // red rect under the iframe: if this is visible, things have gone wrong + builder.push_rect(bounds, None, ColorF::new(1.0, 0.0, 0.0, 1.0)); + builder.push_iframe(bounds, None, sub_pipeline_id); + builder.pop_stacking_context(); +} + +fn event_handler(_event: &glutin::Event, _document_id: DocumentId, _api: &RenderApi) { +} + +fn main() { + boilerplate::main_wrapper(body, event_handler, None); +} diff --git a/gfx/webrender/examples/nested_display_list.rs b/gfx/webrender/examples/nested_display_list.rs index b713ebff6eb8..ffe7f0af959a 100644 --- a/gfx/webrender/examples/nested_display_list.rs +++ b/gfx/webrender/examples/nested_display_list.rs @@ -17,7 +17,9 @@ use std::sync::Mutex; use webrender::api::*; fn body(_api: &RenderApi, + _document_id: &DocumentId, builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, pipeline_id: &PipelineId, layout_size: &LayoutSize) { let bounds = LayoutRect::new(LayoutPoint::zero(), *layout_size); @@ -90,9 +92,7 @@ lazy_static! { static ref CURSOR_POSITION: Mutex = Mutex::new(WorldPoint::zero()); } -fn event_handler(event: &glutin::Event, - api: &RenderApi) -{ +fn event_handler(event: &glutin::Event, document_id: DocumentId, api: &RenderApi) { match *event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { @@ -103,7 +103,8 @@ fn event_handler(event: &glutin::Event, _ => return, }; - api.scroll(ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), + api.scroll(document_id, + ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), *CURSOR_POSITION.lock().unwrap(), ScrollEventPhase::Start); } @@ -121,7 +122,8 @@ fn event_handler(event: &glutin::Event, glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), }; - api.scroll(ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), + api.scroll(document_id, + ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), *CURSOR_POSITION.lock().unwrap(), ScrollEventPhase::Start); } diff --git a/gfx/webrender/examples/scrolling.rs b/gfx/webrender/examples/scrolling.rs index 292db6b97646..7ee2530a2fda 100644 --- a/gfx/webrender/examples/scrolling.rs +++ b/gfx/webrender/examples/scrolling.rs @@ -17,7 +17,9 @@ use std::sync::Mutex; use webrender::api::*; fn body(_api: &RenderApi, + _document_id: &DocumentId, builder: &mut DisplayListBuilder, + _resources: &mut ResourceUpdates, _pipeline_id: &PipelineId, layout_size: &LayoutSize) { let bounds = LayoutRect::new(LayoutPoint::zero(), *layout_size); @@ -99,7 +101,7 @@ lazy_static! { static ref CURSOR_POSITION: Mutex = Mutex::new(WorldPoint::zero()); } -fn event_handler(event: &glutin::Event, api: &RenderApi) { +fn event_handler(event: &glutin::Event, document_id: DocumentId, api: &RenderApi) { match *event { glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { let offset = match key { @@ -110,7 +112,8 @@ fn event_handler(event: &glutin::Event, api: &RenderApi) { _ => return, }; - api.scroll(ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), + api.scroll(document_id, + ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), *CURSOR_POSITION.lock().unwrap(), ScrollEventPhase::Start); } @@ -128,7 +131,8 @@ fn event_handler(event: &glutin::Event, api: &RenderApi) { glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), }; - api.scroll(ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), + api.scroll(document_id, + ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), *CURSOR_POSITION.lock().unwrap(), ScrollEventPhase::Start); } diff --git a/gfx/webrender/examples/yuv.rs b/gfx/webrender/examples/yuv.rs index 4f4a70d0eb89..9246888ddbfb 100644 --- a/gfx/webrender/examples/yuv.rs +++ b/gfx/webrender/examples/yuv.rs @@ -162,7 +162,9 @@ fn main() { } fn body(api: &RenderApi, + _document_id: &DocumentId, builder: &mut DisplayListBuilder, + resources: &mut ResourceUpdates, _pipeline_id: &PipelineId, layout_size: &LayoutSize) { let bounds = LayoutRect::new(LayoutPoint::zero(), *layout_size); @@ -174,30 +176,29 @@ fn body(api: &RenderApi, MixBlendMode::Normal, Vec::new()); - let yuv_chanel1 = api.generate_image_key(); let yuv_chanel2 = api.generate_image_key(); let yuv_chanel2_1 = api.generate_image_key(); let yuv_chanel3 = api.generate_image_key(); - api.add_image( + resources.add_image( yuv_chanel1, ImageDescriptor::new(100, 100, ImageFormat::A8, true), ImageData::new(vec![127; 100 * 100]), None, ); - api.add_image( + resources.add_image( yuv_chanel2, ImageDescriptor::new(100, 100, ImageFormat::RG8, true), ImageData::new(vec![0; 100 * 100 * 2]), None, ); - api.add_image( + resources.add_image( yuv_chanel2_1, ImageDescriptor::new(100, 100, ImageFormat::A8, true), ImageData::new(vec![127; 100 * 100]), None, ); - api.add_image( + resources.add_image( yuv_chanel3, ImageDescriptor::new(100, 100, ImageFormat::A8, true), ImageData::new(vec![127; 100 * 100]), @@ -228,17 +229,17 @@ lazy_static! { } -fn event_handler(event: &glutin::Event, api: &RenderApi) { +fn event_handler(event: &glutin::Event, document_id: DocumentId, api: &RenderApi) { match *event { glutin::Event::Touch(touch) => { match TOUCH_STATE.lock().unwrap().handle_event(touch) { TouchResult::Pan(pan) => { - api.set_pan(pan); - api.generate_frame(None); + api.set_pan(document_id, pan); + api.generate_frame(document_id, None); } TouchResult::Zoom(zoom) => { - api.set_pinch_zoom(ZoomFactor::new(zoom)); - api.generate_frame(None); + api.set_pinch_zoom(document_id, ZoomFactor::new(zoom)); + api.generate_frame(document_id, None); } TouchResult::None => {} } diff --git a/gfx/webrender/res/cs_text_run.vs.glsl b/gfx/webrender/res/cs_text_run.vs.glsl index a0bdd47b6481..ab43c8c4e896 100644 --- a/gfx/webrender/res/cs_text_run.vs.glsl +++ b/gfx/webrender/res/cs_text_run.vs.glsl @@ -24,7 +24,10 @@ void main(void) { PrimitiveGeometry shadow_geom = fetch_primitive_geometry(text_shadow_address); TextShadow shadow = fetch_text_shadow(text_shadow_address + VECS_PER_PRIM_HEADER); - Glyph glyph = fetch_glyph(prim.specific_prim_address, glyph_index); + Glyph glyph = fetch_glyph(prim.specific_prim_address, + glyph_index, + text.subpx_dir); + GlyphResource res = fetch_glyph_resource(resource_address); // Glyphs size is already in device-pixels. diff --git a/gfx/webrender/res/prim_shared.glsl b/gfx/webrender/res/prim_shared.glsl index 7770ca3ff69c..90f89dc573a7 100644 --- a/gfx/webrender/res/prim_shared.glsl +++ b/gfx/webrender/res/prim_shared.glsl @@ -59,6 +59,10 @@ #define LINE_STYLE_DASHED 2 #define LINE_STYLE_WAVY 3 +#define SUBPX_DIR_NONE 0 +#define SUBPX_DIR_HORIZONTAL 1 +#define SUBPX_DIR_VERTICAL 2 + uniform sampler2DArray sCacheA8; uniform sampler2DArray sCacheRGBA8; @@ -419,7 +423,9 @@ struct Glyph { vec2 offset; }; -Glyph fetch_glyph(int specific_prim_address, int glyph_index) { +Glyph fetch_glyph(int specific_prim_address, + int glyph_index, + int subpx_dir) { // Two glyphs are packed in each texel in the GPU cache. int glyph_address = specific_prim_address + VECS_PER_TEXT_RUN + @@ -427,6 +433,20 @@ Glyph fetch_glyph(int specific_prim_address, int glyph_index) { vec4 data = fetch_from_resource_cache_1(glyph_address); // Select XY or ZW based on glyph index. vec2 glyph = mix(data.xy, data.zw, bvec2(glyph_index % 2 == 1)); + + // In subpixel mode, the subpixel offset has already been + // accounted for while rasterizing the glyph. + switch (subpx_dir) { + case SUBPX_DIR_NONE: + break; + case SUBPX_DIR_HORIZONTAL: + glyph.x = trunc(glyph.x); + break; + case SUBPX_DIR_VERTICAL: + glyph.y = trunc(glyph.y); + break; + } + return Glyph(glyph); } @@ -802,11 +822,12 @@ Line fetch_line(int address) { struct TextRun { vec4 color; vec2 offset; + int subpx_dir; }; TextRun fetch_text_run(int address) { vec4 data[2] = fetch_from_resource_cache_2(address); - return TextRun(data[0], data[1].xy); + return TextRun(data[0], data[1].xy, int(data[1].z)); } struct Image { diff --git a/gfx/webrender/res/ps_border_edge.vs.glsl b/gfx/webrender/res/ps_border_edge.vs.glsl index 1f0a94b08869..59e72abbce2d 100644 --- a/gfx/webrender/res/ps_border_edge.vs.glsl +++ b/gfx/webrender/res/ps_border_edge.vs.glsl @@ -37,7 +37,10 @@ void write_alpha_select(float style) { } } -void write_color(vec4 color, float style, bool flip) { +// write_color function is duplicated to work around a Mali-T880 GPU driver program link error. +// See https://github.com/servo/webrender/issues/1403 for more info. +// TODO: convert back to a single function once the driver issues are resolved, if ever. +void write_color0(vec4 color, float style, bool flip) { vec2 modulate; switch (int(style)) { @@ -57,6 +60,27 @@ void write_color(vec4 color, float style, bool flip) { } vColor0 = vec4(color.rgb * modulate.x, color.a); +} + +void write_color1(vec4 color, float style, bool flip) { + vec2 modulate; + + switch (int(style)) { + case BORDER_STYLE_GROOVE: + { + modulate = flip ? vec2(1.3, 0.7) : vec2(0.7, 1.3); + break; + } + case BORDER_STYLE_RIDGE: + { + modulate = flip ? vec2(0.7, 1.3) : vec2(1.3, 0.7); + break; + } + default: + modulate = vec2(1.0); + break; + } + vColor1 = vec4(color.rgb * modulate.y, color.a); } @@ -176,7 +200,8 @@ void main(void) { } write_alpha_select(style); - write_color(color, style, color_flip); + write_color0(color, style, color_flip); + write_color1(color, style, color_flip); #ifdef WR_FEATURE_TRANSFORM TransformVertexInfo vi = write_transform_vertex(segment_rect, diff --git a/gfx/webrender/res/ps_text_run.vs.glsl b/gfx/webrender/res/ps_text_run.vs.glsl index e7c6e81f8785..8e874e3a961a 100644 --- a/gfx/webrender/res/ps_text_run.vs.glsl +++ b/gfx/webrender/res/ps_text_run.vs.glsl @@ -3,33 +3,18 @@ * 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/. */ -#define RENDER_MODE_MONO 0 -#define RENDER_MODE_ALPHA 1 -#define RENDER_MODE_SUBPIXEL 2 - void main(void) { Primitive prim = load_primitive(); TextRun text = fetch_text_run(prim.specific_prim_address); int glyph_index = prim.user_data0; - int render_mode = prim.user_data1; - int resource_address = prim.user_data2; + int resource_address = prim.user_data1; - Glyph glyph = fetch_glyph(prim.specific_prim_address, glyph_index); + Glyph glyph = fetch_glyph(prim.specific_prim_address, + glyph_index, + text.subpx_dir); GlyphResource res = fetch_glyph_resource(resource_address); - switch (render_mode) { - case RENDER_MODE_ALPHA: - break; - case RENDER_MODE_MONO: - break; - case RENDER_MODE_SUBPIXEL: - // In subpixel mode, the subpixel offset has already been - // accounted for while rasterizing the glyph. - glyph.offset = trunc(glyph.offset); - break; - } - vec2 local_pos = glyph.offset + text.offset + vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio; diff --git a/gfx/webrender/src/clip_scroll_tree.rs b/gfx/webrender/src/clip_scroll_tree.rs index 9969188b7920..8bd29d0539cb 100644 --- a/gfx/webrender/src/clip_scroll_tree.rs +++ b/gfx/webrender/src/clip_scroll_tree.rs @@ -3,19 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState}; -use fnv::FnvHasher; +use internal_types::{FastHashSet, FastHashMap}; use print_tree::PrintTree; -use std::collections::{HashMap, HashSet}; -use std::hash::BuildHasherDefault; use api::{ClipId, LayerPoint, LayerRect, LayerToScrollTransform}; use api::{LayerToWorldTransform, PipelineId, ScrollClamping, ScrollEventPhase}; use api::{LayerVector2D, ScrollLayerState, ScrollLocation, WorldPoint}; -pub type ScrollStates = HashMap>; +pub type ScrollStates = FastHashMap; pub struct ClipScrollTree { - pub nodes: HashMap>, - pub pending_scroll_offsets: HashMap, + pub nodes: FastHashMap, + pub pending_scroll_offsets: FastHashMap, /// The ClipId of the currently scrolling node. Used to allow the same /// node to scroll even if a touch operation leaves the boundaries of that node. @@ -36,20 +34,20 @@ pub struct ClipScrollTree { /// A set of pipelines which should be discarded the next time this /// tree is drained. - pub pipelines_to_discard: HashSet, + pub pipelines_to_discard: FastHashSet, } impl ClipScrollTree { pub fn new() -> ClipScrollTree { - let dummy_pipeline = PipelineId(0, 0); + let dummy_pipeline = PipelineId::dummy(); ClipScrollTree { - nodes: HashMap::default(), - pending_scroll_offsets: HashMap::new(), + nodes: FastHashMap::default(), + pending_scroll_offsets: FastHashMap::default(), currently_scrolling_node_id: None, root_reference_frame_id: ClipId::root_reference_frame(dummy_pipeline), topmost_scrolling_node_id: ClipId::root_scroll_node(dummy_pipeline), current_new_node_item: 1, - pipelines_to_discard: HashSet::new(), + pipelines_to_discard: FastHashSet::default(), } } @@ -68,8 +66,8 @@ impl ClipScrollTree { } pub fn collect_nodes_bouncing_back(&self) - -> HashSet> { - let mut nodes_bouncing_back = HashSet::default(); + -> FastHashSet { + let mut nodes_bouncing_back = FastHashSet::default(); for (clip_id, node) in self.nodes.iter() { if let NodeType::ScrollFrame(ref scrolling) = node.node_type { if scrolling.bouncing_back { @@ -123,7 +121,7 @@ impl ClipScrollTree { pub fn drain(&mut self) -> ScrollStates { self.current_new_node_item = 1; - let mut scroll_states = HashMap::default(); + let mut scroll_states = FastHashMap::default(); for (layer_id, old_node) in &mut self.nodes.drain() { if self.pipelines_to_discard.contains(&layer_id.pipeline_id()) { continue; diff --git a/gfx/webrender/src/debug_render.rs b/gfx/webrender/src/debug_render.rs index 036602856373..9b4b33e8b047 100644 --- a/gfx/webrender/src/debug_render.rs +++ b/gfx/webrender/src/debug_render.rs @@ -3,18 +3,73 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use debug_font_data; -use device::{Device, GpuMarker, ProgramId, VAOId, TextureId, VertexFormat}; -use device::{TextureFilter, VertexUsageHint, TextureTarget}; +use device::{Device, GpuMarker, Program, VAOId, TextureId, VertexDescriptor}; +use device::{TextureFilter, VertexAttribute, VertexUsageHint, VertexAttributeKind, TextureTarget}; use euclid::{Transform3D, Point2D, Size2D, Rect}; use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, TextureSampler}; -use internal_types::{DebugFontVertex, DebugColorVertex, RenderTargetMode}; +use internal_types::RenderTargetMode; use std::f32; use api::{ColorU, ImageFormat, DeviceUintSize}; +const DESC_FONT: VertexDescriptor = VertexDescriptor { + vertex_attributes: &[ + VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm }, + VertexAttribute { name: "aColorTexCoord", count: 2, kind: VertexAttributeKind::F32 }, + ], + instance_attributes: &[] +}; + +const DESC_COLOR: VertexDescriptor = VertexDescriptor { + vertex_attributes: &[ + VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm }, + ], + instance_attributes: &[] +}; + +#[repr(C)] +pub struct DebugFontVertex { + pub x: f32, + pub y: f32, + pub color: ColorU, + pub u: f32, + pub v: f32, +} + +impl DebugFontVertex { + pub fn new(x: f32, y: f32, u: f32, v: f32, color: ColorU) -> DebugFontVertex { + DebugFontVertex { + x, + y, + color, + u, + v, + } + } +} + +#[repr(C)] +pub struct DebugColorVertex { + pub x: f32, + pub y: f32, + pub color: ColorU, +} + +impl DebugColorVertex { + pub fn new(x: f32, y: f32, color: ColorU) -> DebugColorVertex { + DebugColorVertex { + x, + y, + color, + } + } +} + pub struct DebugRenderer { font_vertices: Vec, font_indices: Vec, - font_program_id: ProgramId, + font_program: Program, font_vao: VAOId, font_texture_id: TextureId, @@ -23,17 +78,17 @@ pub struct DebugRenderer { tri_vao: VAOId, line_vertices: Vec, line_vao: VAOId, - color_program_id: ProgramId, + color_program: Program, } impl DebugRenderer { pub fn new(device: &mut Device) -> DebugRenderer { - let font_program_id = device.create_program("debug_font", "shared_other", VertexFormat::DebugFont).unwrap(); - let color_program_id = device.create_program("debug_color", "shared_other", VertexFormat::DebugColor).unwrap(); + let font_program = device.create_program("debug_font", "shared_other", &DESC_FONT).unwrap(); + let color_program = device.create_program("debug_color", "shared_other", &DESC_COLOR).unwrap(); - let font_vao = device.create_vao(VertexFormat::DebugFont, 32); - let line_vao = device.create_vao(VertexFormat::DebugColor, 32); - let tri_vao = device.create_vao(VertexFormat::DebugColor, 32); + let font_vao = device.create_vao(&DESC_FONT, 32); + let line_vao = device.create_vao(&DESC_COLOR, 32); + let tri_vao = device.create_vao(&DESC_COLOR, 32); let font_texture_id = device.create_texture_ids(1, TextureTarget::Default)[0]; device.init_texture(font_texture_id, @@ -51,14 +106,19 @@ impl DebugRenderer { tri_vao, tri_vertices: Vec::new(), tri_indices: Vec::new(), - font_program_id, - color_program_id, + font_program, + color_program, font_vao, line_vao, font_texture_id, } } + pub fn deinit(&mut self, device: &mut Device) { + device.delete_program(&mut self.font_program); + device.delete_program(&mut self.color_program); + } + pub fn line_height(&self) -> f32 { debug_font_data::FONT_SIZE as f32 * 1.1 } @@ -170,7 +230,8 @@ impl DebugRenderer { // Triangles if !self.tri_vertices.is_empty() { - device.bind_program(self.color_program_id, &projection); + device.bind_program(&self.color_program); + device.set_uniforms(&self.color_program, &projection); device.bind_vao(self.tri_vao); device.update_vao_indices(self.tri_vao, &self.tri_indices, @@ -183,7 +244,8 @@ impl DebugRenderer { // Lines if !self.line_vertices.is_empty() { - device.bind_program(self.color_program_id, &projection); + device.bind_program(&self.color_program); + device.set_uniforms(&self.color_program, &projection); device.bind_vao(self.line_vao); device.update_vao_main_vertices(self.line_vao, &self.line_vertices, @@ -193,7 +255,8 @@ impl DebugRenderer { // Glyph if !self.font_indices.is_empty() { - device.bind_program(self.font_program_id, &projection); + device.bind_program(&self.font_program); + device.set_uniforms(&self.font_program, &projection); device.bind_texture(TextureSampler::Color0, self.font_texture_id); device.bind_vao(self.font_vao); device.update_vao_indices(self.font_vao, diff --git a/gfx/webrender/src/device.rs b/gfx/webrender/src/device.rs index 5e7a7cfb314d..66262679d417 100644 --- a/gfx/webrender/src/device.rs +++ b/gfx/webrender/src/device.rs @@ -3,16 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use euclid::Transform3D; -use fnv::FnvHasher; use gleam::gl; -use internal_types::{PackedVertex, RenderTargetMode, TextureSampler, DEFAULT_TEXTURE}; -use internal_types::{BlurAttribute, ClipAttribute, VertexAttribute}; -use internal_types::{DebugFontVertex, DebugColorVertex}; +use internal_types::{RenderTargetMode, TextureSampler, DEFAULT_TEXTURE, FastHashMap}; //use notify::{self, Watcher}; use super::shader_source; -use std::collections::HashMap; use std::fs::File; -use std::hash::BuildHasherDefault; use std::io::Read; use std::iter::repeat; use std::mem; @@ -21,7 +16,7 @@ use std::path::PathBuf; use std::ptr; use std::rc::Rc; //use std::sync::mpsc::{channel, Sender}; -//use std::thread; +use std::thread; use api::{ColorF, ImageFormat}; use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintSize}; @@ -89,13 +84,24 @@ pub enum TextureFilter { Linear, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum VertexFormat { - Triangles, - DebugFont, - DebugColor, - Blur, - Clip, +#[derive(Debug)] +pub enum VertexAttributeKind { + F32, + U8Norm, + I32, +} + +#[derive(Debug)] +pub struct VertexAttribute { + pub name: &'static str, + pub count: u32, + pub kind: VertexAttributeKind, +} + +#[derive(Debug)] +pub struct VertexDescriptor { + pub vertex_attributes: &'static [VertexAttribute], + pub instance_attributes: &'static [VertexAttribute], } enum FBOTarget { @@ -147,146 +153,97 @@ pub trait FileWatcherHandler : Send { fn file_changed(&self, path: PathBuf); } -impl VertexFormat { - fn bind(&self, gl: &gl::Gl, main: VBOId, instance: VBOId, offset: gl::GLuint, instance_stride: gl::GLint) { +impl VertexAttributeKind { + fn size_in_bytes(&self) -> u32 { + match *self { + VertexAttributeKind::F32 => 4, + VertexAttributeKind::U8Norm => 1, + VertexAttributeKind::I32 => 4, + } + } +} + +impl VertexAttribute { + fn size_in_bytes(&self) -> u32 { + self.count * self.kind.size_in_bytes() + } + + fn bind_to_vao(&self, + attr_index: gl::GLuint, + divisor: gl::GLuint, + stride: gl::GLint, + offset: gl::GLuint, + gl: &gl::Gl) { + gl.enable_vertex_attrib_array(attr_index); + gl.vertex_attrib_divisor(attr_index, divisor); + + match self.kind { + VertexAttributeKind::F32 => { + gl.vertex_attrib_pointer(attr_index, + self.count as gl::GLint, + gl::FLOAT, + false, + stride, + offset); + } + VertexAttributeKind::U8Norm => { + gl.vertex_attrib_pointer(attr_index, + self.count as gl::GLint, + gl::UNSIGNED_BYTE, + true, + stride, + offset); + } + VertexAttributeKind::I32 => { + gl.vertex_attrib_i_pointer(attr_index, + self.count as gl::GLint, + gl::INT, + stride, + offset); + } + } + } +} + +impl VertexDescriptor { + fn bind(&self, + gl: &gl::Gl, + main: VBOId, + instance: VBOId) { main.bind(gl); - match *self { - VertexFormat::DebugFont => { - gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - gl.enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint); - gl.enable_vertex_attrib_array(VertexAttribute::ColorTexCoord as gl::GLuint); + let vertex_stride: u32 = self.vertex_attributes + .iter() + .map(|attr| attr.size_in_bytes()).sum(); + let mut vertex_offset = 0; - gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); - gl.vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0); - gl.vertex_attrib_divisor(VertexAttribute::ColorTexCoord as gl::GLuint, 0); + for (i, attr) in self.vertex_attributes.iter().enumerate() { + let attr_index = i as gl::GLuint; + attr.bind_to_vao(attr_index, + 0, + vertex_stride as gl::GLint, + vertex_offset, + gl); + vertex_offset += attr.size_in_bytes(); + } - let vertex_stride = mem::size_of::() as gl::GLuint; + if !self.instance_attributes.is_empty() { + instance.bind(gl); + let instance_stride: u32 = self.instance_attributes + .iter() + .map(|attr| attr.size_in_bytes()).sum(); + let mut instance_offset = 0; - gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0 + vertex_stride * offset); - gl.vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - true, - vertex_stride as gl::GLint, - 8 + vertex_stride * offset); - gl.vertex_attrib_pointer(VertexAttribute::ColorTexCoord as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 12 + vertex_stride * offset); - } - VertexFormat::DebugColor => { - gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - gl.enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint); + let base_attr = self.vertex_attributes.len() as u32; - gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); - gl.vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0); - - let vertex_stride = mem::size_of::() as gl::GLuint; - - gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0 + vertex_stride * offset); - gl.vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint, - 4, - gl::UNSIGNED_BYTE, - true, - vertex_stride as gl::GLint, - 8 + vertex_stride * offset); - } - VertexFormat::Triangles => { - let vertex_stride = mem::size_of::() as gl::GLuint; - gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint); - gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0); - - gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0); - - instance.bind(gl); - let mut offset = 0; - - for &attrib in [VertexAttribute::Data0, - VertexAttribute::Data1, - ].into_iter() { - gl.enable_vertex_attrib_array(attrib as gl::GLuint); - gl.vertex_attrib_divisor(attrib as gl::GLuint, 1); - gl.vertex_attrib_i_pointer(attrib as gl::GLuint, - 4, - gl::INT, - instance_stride, - offset); - offset += 16; - } - } - VertexFormat::Blur => { - let vertex_stride = mem::size_of::() as gl::GLuint; - gl.enable_vertex_attrib_array(BlurAttribute::Position as gl::GLuint); - gl.vertex_attrib_divisor(BlurAttribute::Position as gl::GLuint, 0); - - gl.vertex_attrib_pointer(BlurAttribute::Position as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0); - - instance.bind(gl); - - for (i, &attrib) in [BlurAttribute::RenderTaskIndex, - BlurAttribute::SourceTaskIndex, - BlurAttribute::Direction, - ].into_iter().enumerate() { - gl.enable_vertex_attrib_array(attrib as gl::GLuint); - gl.vertex_attrib_divisor(attrib as gl::GLuint, 1); - gl.vertex_attrib_i_pointer(attrib as gl::GLuint, - 1, - gl::INT, - instance_stride, - (i * 4) as gl::GLuint); - } - } - VertexFormat::Clip => { - let vertex_stride = mem::size_of::() as gl::GLuint; - gl.enable_vertex_attrib_array(ClipAttribute::Position as gl::GLuint); - gl.vertex_attrib_divisor(ClipAttribute::Position as gl::GLuint, 0); - - gl.vertex_attrib_pointer(ClipAttribute::Position as gl::GLuint, - 2, - gl::FLOAT, - false, - vertex_stride as gl::GLint, - 0); - - instance.bind(gl); - - for (i, &attrib) in [ClipAttribute::RenderTaskIndex, - ClipAttribute::LayerIndex, - ClipAttribute::DataIndex, - ClipAttribute::SegmentIndex, - ClipAttribute::ResourceAddress, - ].into_iter().enumerate() { - gl.enable_vertex_attrib_array(attrib as gl::GLuint); - gl.vertex_attrib_divisor(attrib as gl::GLuint, 1); - gl.vertex_attrib_i_pointer(attrib as gl::GLuint, - 1, - gl::INT, - instance_stride, - (i * 4) as gl::GLuint); - } + for (i, attr) in self.instance_attributes.iter().enumerate() { + let attr_index = base_attr + i as u32; + attr.bind_to_vao(attr_index, + 1, + instance_stride as gl::GLint, + instance_offset, + gl); + instance_offset += attr.size_in_bytes(); } } } @@ -314,12 +271,6 @@ impl TextureId { pub fn is_valid(&self) -> bool { *self != TextureId::invalid() } } -impl ProgramId { - fn bind(&self, gl: &gl::Gl) { - gl.use_program(self.0); - } -} - impl VBOId { fn bind(&self, gl: &gl::Gl) { gl.bind_buffer(gl::ARRAY_BUFFER, self.0); @@ -332,12 +283,6 @@ impl IBOId { } } -impl UBOId { - fn _bind(&self, gl: &gl::Gl) { - gl.bind_buffer(gl::UNIFORM_BUFFER, self.0); - } -} - impl FBOId { fn bind(&self, gl: &gl::Gl, target: FBOTarget) { let target = match target { @@ -371,8 +316,7 @@ impl Drop for Texture { } } -struct Program { - gl: Rc, +pub struct Program { id: gl::GLuint, u_transform: gl::GLint, u_device_pixel_ratio: gl::GLint, @@ -388,43 +332,26 @@ impl Program { fn attach_and_bind_shaders(&mut self, vs_id: gl::GLuint, fs_id: gl::GLuint, - vertex_format: VertexFormat) -> Result<(), ShaderError> { - self.gl.attach_shader(self.id, vs_id); - self.gl.attach_shader(self.id, fs_id); + descriptor: &VertexDescriptor, + gl: &gl::Gl) -> Result<(), ShaderError> { + gl.attach_shader(self.id, vs_id); + gl.attach_shader(self.id, fs_id); - match vertex_format { - VertexFormat::Triangles | - VertexFormat::DebugFont | - VertexFormat::DebugColor => { - self.gl.bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition"); - self.gl.bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor"); - self.gl.bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord"); - - self.gl.bind_attrib_location(self.id, VertexAttribute::Data0 as gl::GLuint, "aData0"); - self.gl.bind_attrib_location(self.id, VertexAttribute::Data1 as gl::GLuint, "aData1"); - } - VertexFormat::Blur => { - self.gl.bind_attrib_location(self.id, BlurAttribute::Position as gl::GLuint, "aPosition"); - self.gl.bind_attrib_location(self.id, BlurAttribute::RenderTaskIndex as gl::GLuint, "aBlurRenderTaskIndex"); - self.gl.bind_attrib_location(self.id, BlurAttribute::SourceTaskIndex as gl::GLuint, "aBlurSourceTaskIndex"); - self.gl.bind_attrib_location(self.id, BlurAttribute::Direction as gl::GLuint, "aBlurDirection"); - } - VertexFormat::Clip => { - self.gl.bind_attrib_location(self.id, ClipAttribute::Position as gl::GLuint, "aPosition"); - self.gl.bind_attrib_location(self.id, ClipAttribute::RenderTaskIndex as gl::GLuint, "aClipRenderTaskIndex"); - self.gl.bind_attrib_location(self.id, ClipAttribute::LayerIndex as gl::GLuint, "aClipLayerIndex"); - self.gl.bind_attrib_location(self.id, ClipAttribute::DataIndex as gl::GLuint, "aClipDataIndex"); - self.gl.bind_attrib_location(self.id, ClipAttribute::SegmentIndex as gl::GLuint, "aClipSegmentIndex"); - self.gl.bind_attrib_location(self.id, ClipAttribute::ResourceAddress as gl::GLuint, "aClipResourceAddress"); - } + for (i, attr) in descriptor.vertex_attributes + .iter() + .chain(descriptor.instance_attributes.iter()) + .enumerate() { + gl.bind_attrib_location(self.id, + i as gl::GLuint, + attr.name); } - self.gl.link_program(self.id); - if self.gl.get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) { - let error_log = self.gl.get_program_info_log(self.id); + gl.link_program(self.id); + if gl.get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) { + let error_log = gl.get_program_info_log(self.id); println!("Failed to link shader program: {:?}\n{}", self.name, error_log); - self.gl.detach_shader(self.id, vs_id); - self.gl.detach_shader(self.id, fs_id); + gl.detach_shader(self.id, vs_id); + gl.detach_shader(self.id, fs_id); return Err(ShaderError::Link(self.name.clone(), error_log)); } @@ -434,7 +361,7 @@ impl Program { impl Drop for Program { fn drop(&mut self) { - self.gl.delete_program(self.id); + debug_assert!(thread::panicking() || self.id == 0); } } @@ -473,9 +400,6 @@ pub struct TextureId { target: gl::GLuint, } -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] -pub struct ProgramId(pub gl::GLuint); - #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] pub struct VAOId(gl::GLuint); @@ -491,9 +415,6 @@ pub struct VBOId(gl::GLuint); #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] struct IBOId(gl::GLuint); -#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] -pub struct UBOId(gl::GLuint); - #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] pub struct PBOId(gl::GLuint); @@ -839,7 +760,6 @@ impl FileWatcherThread { */ pub struct Capabilities { - pub max_ubo_size: usize, pub supports_multisampling: bool, } @@ -853,7 +773,7 @@ pub struct Device { gl: Rc, // device state bound_textures: [TextureId; 16], - bound_program: ProgramId, + bound_program: gl::GLuint, bound_vao: VAOId, bound_pbo: PBOId, bound_read_fbo: FBOId, @@ -870,9 +790,8 @@ pub struct Device { // resources resource_override_path: Option, - textures: HashMap>, - programs: HashMap>, - vaos: HashMap>, + textures: FastHashMap, + vaos: FastHashMap, // misc. shader_preamble: String, @@ -898,7 +817,6 @@ impl Device { let shader_preamble = get_shader_source(SHADER_PREAMBLE, &resource_override_path); //file_watcher.add_watch(resource_path); - let max_ubo_size = gl.get_integer_v(gl::MAX_UNIFORM_BLOCK_SIZE) as usize; let max_texture_size = gl.get_integer_v(gl::MAX_TEXTURE_SIZE) as u32; Device { @@ -910,12 +828,11 @@ impl Device { inside_frame: false, capabilities: Capabilities { - max_ubo_size, supports_multisampling: false, //TODO }, bound_textures: [ TextureId::invalid(); 16 ], - bound_program: ProgramId(0), + bound_program: 0, bound_vao: VAOId(0), bound_pbo: PBOId(0), bound_read_fbo: FBOId(0), @@ -923,9 +840,8 @@ impl Device { default_read_fbo: 0, default_draw_fbo: 0, - textures: HashMap::default(), - programs: HashMap::default(), - vaos: HashMap::default(), + textures: FastHashMap::default(), + vaos: FastHashMap::default(), shader_preamble, @@ -1004,7 +920,7 @@ impl Device { } // Shader state - self.bound_program = ProgramId(0); + self.bound_program = 0; self.gl.use_program(0); // Vertex state @@ -1072,20 +988,13 @@ impl Device { } } - pub fn bind_program(&mut self, - program_id: ProgramId, - projection: &Transform3D) { + pub fn bind_program(&mut self, program: &Program) { debug_assert!(self.inside_frame); - if self.bound_program != program_id { - self.bound_program = program_id; - program_id.bind(&*self.gl); + if self.bound_program != program.id { + self.gl.use_program(program.id); + self.bound_program = program.id; } - - let program = self.programs.get(&program_id).unwrap(); - self.set_uniforms(program, - projection, - self.device_pixel_ratio); } pub fn create_texture_ids(&mut self, @@ -1436,15 +1345,23 @@ impl Device { pub fn create_program(&mut self, base_filename: &str, include_filename: &str, - vertex_format: VertexFormat) -> Result { - self.create_program_with_prefix(base_filename, &[include_filename], None, vertex_format) + descriptor: &VertexDescriptor) -> Result { + self.create_program_with_prefix(base_filename, + &[include_filename], + None, + descriptor) + } + + pub fn delete_program(&mut self, program: &mut Program) { + self.gl.delete_program(program.id); + program.id = 0; } pub fn create_program_with_prefix(&mut self, base_filename: &str, include_filenames: &[&str], prefix: Option, - vertex_format: VertexFormat) -> Result { + descriptor: &VertexDescriptor) -> Result { debug_assert!(self.inside_frame); let pid = self.gl.create_program(); @@ -1464,8 +1381,7 @@ impl Device { include.push_str(&shared_src); } - let program = Program { - gl: Rc::clone(&self.gl), + let mut program = Program { name: base_filename.to_owned(), id: pid, u_transform: -1, @@ -1477,24 +1393,17 @@ impl Device { fs_id: None, }; - let program_id = ProgramId(pid); + try!{ self.load_program(&mut program, include, descriptor) }; - debug_assert!(self.programs.contains_key(&program_id) == false); - self.programs.insert(program_id, program); - - try!{ self.load_program(program_id, include, vertex_format) }; - - Ok(program_id) + Ok(program) } fn load_program(&mut self, - program_id: ProgramId, + program: &mut Program, include: String, - vertex_format: VertexFormat) -> Result<(), ShaderError> { + descriptor: &VertexDescriptor) -> Result<(), ShaderError> { debug_assert!(self.inside_frame); - let program = self.programs.get_mut(&program_id).unwrap(); - let mut vs_preamble = Vec::new(); let mut fs_preamble = Vec::new(); @@ -1532,9 +1441,9 @@ impl Device { self.gl.detach_shader(program.id, fs_id); } - if let Err(bind_error) = program.attach_and_bind_shaders(vs_id, fs_id, vertex_format) { + if let Err(bind_error) = program.attach_and_bind_shaders(vs_id, fs_id, descriptor, &*self.gl) { if let (Some(vs_id), Some(fs_id)) = (program.vs_id, program.fs_id) { - try! { program.attach_and_bind_shaders(vs_id, fs_id, vertex_format) }; + try! { program.attach_and_bind_shaders(vs_id, fs_id, descriptor, &*self.gl) }; } else { return Err(bind_error); } @@ -1554,7 +1463,7 @@ impl Device { program.u_transform = self.gl.get_uniform_location(program.id, "uTransform"); program.u_device_pixel_ratio = self.gl.get_uniform_location(program.id, "uDevicePixelRatio"); - program_id.bind(&*self.gl); + self.bind_program(program); let u_color_0 = self.gl.get_uniform_location(program.id, "sColor0"); if u_color_0 != -1 { self.gl.uniform_1i(u_color_0, TextureSampler::Color0 as i32); @@ -1635,9 +1544,8 @@ impl Device { } }*/ - pub fn get_uniform_location(&self, program_id: ProgramId, name: &str) -> UniformLocation { - let ProgramId(program_id) = program_id; - UniformLocation(self.gl.get_uniform_location(program_id, name)) + pub fn get_uniform_location(&self, program: &Program, name: &str) -> UniformLocation { + UniformLocation(self.gl.get_uniform_location(program.id, name)) } pub fn set_uniform_2f(&self, uniform: UniformLocation, x: f32, y: f32) { @@ -1646,15 +1554,14 @@ impl Device { self.gl.uniform_2f(location, x, y); } - fn set_uniforms(&self, - program: &Program, - transform: &Transform3D, - device_pixel_ratio: f32) { + pub fn set_uniforms(&self, + program: &Program, + transform: &Transform3D) { debug_assert!(self.inside_frame); self.gl.uniform_matrix_4fv(program.u_transform, - false, - &transform.to_row_major_array()); - self.gl.uniform_1f(program.u_device_pixel_ratio, device_pixel_ratio); + false, + &transform.to_row_major_array()); + self.gl.uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio); } pub fn create_pbo(&mut self) -> PBOId { @@ -1797,11 +1704,10 @@ impl Device { } fn create_vao_with_vbos(&mut self, - format: VertexFormat, + descriptor: &VertexDescriptor, main_vbo_id: VBOId, instance_vbo_id: VBOId, ibo_id: IBOId, - vertex_offset: gl::GLuint, instance_stride: gl::GLint, owns_vertices: bool, owns_instances: bool, @@ -1814,7 +1720,7 @@ impl Device { self.gl.bind_vertex_array(vao_id); - format.bind(self.gl(), main_vbo_id, instance_vbo_id, vertex_offset, instance_stride); + descriptor.bind(self.gl(), main_vbo_id, instance_vbo_id); ibo_id.bind(self.gl()); // force it to be a part of VAO let vao = VAO { @@ -1839,7 +1745,9 @@ impl Device { vao_id } - pub fn create_vao(&mut self, format: VertexFormat, inst_stride: gl::GLint) -> VAOId { + pub fn create_vao(&mut self, + descriptor: &VertexDescriptor, + inst_stride: gl::GLint) -> VAOId { debug_assert!(self.inside_frame); let buffer_ids = self.gl.gen_buffers(3); @@ -1847,10 +1755,19 @@ impl Device { let main_vbo_id = VBOId(buffer_ids[1]); let intance_vbo_id = VBOId(buffer_ids[2]); - self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, true, true, true) + self.create_vao_with_vbos(descriptor, + main_vbo_id, + intance_vbo_id, + ibo_id, + inst_stride, + true, + true, + true) } - pub fn create_vao_with_new_instances(&mut self, format: VertexFormat, inst_stride: gl::GLint, + pub fn create_vao_with_new_instances(&mut self, + descriptor: &VertexDescriptor, + inst_stride: gl::GLint, base_vao: VAOId) -> VAOId { debug_assert!(self.inside_frame); @@ -1861,7 +1778,14 @@ impl Device { (vao.main_vbo_id, vao.ibo_id) }; - self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, false, true, false) + self.create_vao_with_vbos(descriptor, + main_vbo_id, + intance_vbo_id, + ibo_id, + inst_stride, + false, + true, + false) } pub fn update_vao_main_vertices(&mut self, @@ -1954,44 +1878,6 @@ impl Device { self.frame_id.0 += 1; } - pub fn assign_ubo_binding(&self, program_id: ProgramId, name: &str, value: u32) -> u32 { - let index = self.gl.get_uniform_block_index(program_id.0, name); - self.gl.uniform_block_binding(program_id.0, index, value); - index - } - - pub fn create_ubo(&self, data: &[T], binding: u32) -> UBOId { - let ubo = self.gl.gen_buffers(1)[0]; - self.gl.bind_buffer(gl::UNIFORM_BUFFER, ubo); - gl::buffer_data(self.gl(), gl::UNIFORM_BUFFER, data, gl::STATIC_DRAW); - self.gl.bind_buffer_base(gl::UNIFORM_BUFFER, binding, ubo); - UBOId(ubo) - } - - pub fn reset_ubo(&self, binding: u32) { - self.gl.bind_buffer(gl::UNIFORM_BUFFER, 0); - self.gl.bind_buffer_base(gl::UNIFORM_BUFFER, binding, 0); - } - - pub fn delete_buffer(&self, buffer: UBOId) { - self.gl.delete_buffers(&[buffer.0]); - } - - #[cfg(target_os = "android")] - pub fn set_multisample(&self, enable: bool) { - } - - #[cfg(not(target_os = "android"))] - pub fn set_multisample(&self, enable: bool) { - if self.capabilities.supports_multisampling { - if enable { - self.gl.enable(gl::MULTISAMPLE); - } else { - self.gl.disable(gl::MULTISAMPLE); - } - } - } - pub fn clear_target(&self, color: Option<[f32; 4]>, depth: Option) { diff --git a/gfx/webrender/src/frame.rs b/gfx/webrender/src/frame.rs index ea55be2b26d1..98a3647e871c 100644 --- a/gfx/webrender/src/frame.rs +++ b/gfx/webrender/src/frame.rs @@ -11,17 +11,13 @@ use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, use api::{TransformStyle, WorldPoint}; use clip_scroll_tree::{ClipScrollTree, ScrollStates}; use euclid::rect; -use fnv::FnvHasher; use gpu_cache::GpuCache; -use internal_types::{RendererFrame}; +use internal_types::{FastHashMap, RendererFrame}; use frame_builder::{FrameBuilder, FrameBuilderConfig}; use mask_cache::ClipRegion; use profiler::{GpuCacheProfileCounters, TextureCacheProfileCounters}; -use resource_cache::ResourceCache; +use resource_cache::{ResourceCache, TiledImageMap}; use scene::{Scene, SceneProperties}; -use std::cmp; -use std::collections::HashMap; -use std::hash::BuildHasherDefault; use tiling::{CompositeOps, DisplayListMap, PrimitiveFlags}; use util::{ComplexClipRegionHelpers, subtract_rect}; @@ -91,7 +87,7 @@ impl NestedDisplayListInfo { struct FlattenContext<'a> { scene: &'a Scene, builder: &'a mut FrameBuilder, - resource_cache: &'a mut ResourceCache, + tiled_image_map: TiledImageMap, replacements: Vec<(ClipId, ClipId)>, nested_display_list_info: Vec, current_nested_display_list_index: u64, @@ -100,12 +96,12 @@ struct FlattenContext<'a> { impl<'a> FlattenContext<'a> { fn new(scene: &'a Scene, builder: &'a mut FrameBuilder, - resource_cache: &'a mut ResourceCache) + resource_cache: &ResourceCache) -> FlattenContext<'a> { FlattenContext { scene, builder, - resource_cache, + tiled_image_map: resource_cache.get_tiled_image_map(), replacements: Vec::new(), nested_display_list_info: Vec::new(), current_nested_display_list_index: 0, @@ -177,7 +173,7 @@ impl<'a> FlattenContext<'a> { // TODO: doc pub struct Frame { pub clip_scroll_tree: ClipScrollTree, - pub pipeline_epoch_map: HashMap>, + pub pipeline_epoch_map: FastHashMap, id: FrameId, frame_builder_config: FrameBuilderConfig, frame_builder: Option, @@ -222,7 +218,7 @@ impl StackingContextHelpers for StackingContext { impl Frame { pub fn new(config: FrameBuilderConfig) -> Frame { Frame { - pipeline_epoch_map: HashMap::default(), + pipeline_epoch_map: FastHashMap::default(), clip_scroll_tree: ClipScrollTree::new(), id: FrameId(0), frame_builder: None, @@ -539,19 +535,16 @@ impl Frame { info.context_id); } SpecificDisplayItem::Image(ref info) => { - let image = context.resource_cache.get_image_properties(info.image_key); - if let Some(tile_size) = image.tiling { + if let Some(tiling) = context.tiled_image_map.get(&info.image_key) { // The image resource is tiled. We have to generate an image primitive // for each tile. - let image_size = DeviceUintSize::new(image.descriptor.width, - image.descriptor.height); self.decompose_image(clip_and_scroll, - context, + &mut context.builder, &item_rect_with_offset, &clip_with_offset, info, - image_size, - tile_size as u32); + tiling.image_size, + tiling.tile_size as u32); } else { context.builder.add_image(clip_and_scroll, item_rect_with_offset, @@ -878,7 +871,7 @@ impl Frame { /// takes care of the decomposition required by the internal tiling of the image. fn decompose_image(&mut self, clip_and_scroll: ClipAndScrollInfo, - context: &mut FlattenContext, + builder: &mut FrameBuilder, item_rect: &LayerRect, item_local_clip: &LocalClip, info: &ImageDisplayItem, @@ -888,7 +881,7 @@ impl Frame { let no_vertical_spacing = info.tile_spacing.height == 0.0; if no_vertical_tiling && no_vertical_spacing { self.decompose_image_row(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -908,7 +901,7 @@ impl Frame { info.stretch_size.height ).intersection(item_rect) { self.decompose_image_row(clip_and_scroll, - context, + builder, &row_rect, item_local_clip, info, @@ -920,7 +913,7 @@ impl Frame { fn decompose_image_row(&mut self, clip_and_scroll: ClipAndScrollInfo, - context: &mut FlattenContext, + builder: &mut FrameBuilder, item_rect: &LayerRect, item_local_clip: &LocalClip, info: &ImageDisplayItem, @@ -930,7 +923,7 @@ impl Frame { let no_horizontal_spacing = info.tile_spacing.width == 0.0; if no_horizontal_tiling && no_horizontal_spacing { self.decompose_tiled_image(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -950,7 +943,7 @@ impl Frame { item_rect.size.height, ).intersection(item_rect) { self.decompose_tiled_image(clip_and_scroll, - context, + builder, &decomposed_rect, item_local_clip, info, @@ -962,7 +955,7 @@ impl Frame { fn decompose_tiled_image(&mut self, clip_and_scroll: ClipAndScrollInfo, - context: &mut FlattenContext, + builder: &mut FrameBuilder, item_rect: &LayerRect, item_local_clip: &LocalClip, info: &ImageDisplayItem, @@ -1005,14 +998,14 @@ impl Frame { if info.stretch_size.width < item_rect.size.width { // If this assert blows up it means we haven't properly decomposed the image in decompose_image_row. debug_assert!(image_size.width <= tile_size); - // we don't actually tile in this dimmension so repeating can be done in the shader. + // we don't actually tile in this dimension so repeating can be done in the shader. repeat_x = true; } if info.stretch_size.height < item_rect.size.height { // If this assert blows up it means we haven't properly decomposed the image in decompose_image. debug_assert!(image_size.height <= tile_size); - // we don't actually tile in this dimmension so repeating can be done in the shader. + // we don't actually tile in this dimension so repeating can be done in the shader. repeat_y = true; } @@ -1041,7 +1034,7 @@ impl Frame { for ty in 0..num_tiles_y { for tx in 0..num_tiles_x { self.add_tile_primitive(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -1053,7 +1046,7 @@ impl Frame { if leftover.width != 0 { // Tiles on the right edge that are smaller than the tile size. self.add_tile_primitive(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -1069,7 +1062,7 @@ impl Frame { for tx in 0..num_tiles_x { // Tiles on the bottom edge that are smaller than the tile size. self.add_tile_primitive(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -1084,7 +1077,7 @@ impl Frame { if leftover.width != 0 { // Finally, the bottom-right tile with a "leftover" size. self.add_tile_primitive(clip_and_scroll, - context, + builder, item_rect, item_local_clip, info, @@ -1100,7 +1093,7 @@ impl Frame { fn add_tile_primitive(&mut self, clip_and_scroll: ClipAndScrollInfo, - context: &mut FlattenContext, + builder: &mut FrameBuilder, item_rect: &LayerRect, item_local_clip: &LocalClip, info: &ImageDisplayItem, @@ -1144,15 +1137,15 @@ impl Frame { // Fix up the primitive's rect if it overflows the original item rect. if let Some(prim_rect) = prim_rect.intersection(item_rect) { - context.builder.add_image(clip_and_scroll, - prim_rect, - item_local_clip, - &stretched_size, - &info.tile_spacing, - None, - info.image_key, - info.image_rendering, - Some(tile_offset)); + builder.add_image(clip_and_scroll, + prim_rect, + item_local_clip, + &stretched_size, + &info.tile_spacing, + None, + info.image_key, + info.image_rendering, + Some(tile_offset)); } } @@ -1172,10 +1165,6 @@ impl Frame { device_pixel_ratio, texture_cache_profile, gpu_cache_profile); - // Expire any resources that haven't been used for `cache_expiry_frames`. - let num_frames_back = self.frame_builder_config.cache_expiry_frames; - let expiry_frame = FrameId(cmp::max(num_frames_back, self.id.0) - num_frames_back); - resource_cache.expire_old_resources(expiry_frame); frame } diff --git a/gfx/webrender/src/frame_builder.rs b/gfx/webrender/src/frame_builder.rs index bab92a444ee6..8272c0712746 100644 --- a/gfx/webrender/src/frame_builder.rs +++ b/gfx/webrender/src/frame_builder.rs @@ -5,15 +5,14 @@ use api::{BorderDetails, BorderDisplayItem, BoxShadowClipMode, ClipAndScrollInfo, ClipId, ColorF}; use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize}; use api::{ExtendMode, FontKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop}; -use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize}; +use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize, SubpixelDirection}; use api::{LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation, LineStyle}; use api::{LocalClip, PipelineId, RepeatMode, ScrollSensitivity, TextShadow, TileOffset}; use api::{TransformStyle, WebGLContextId, WorldPixel, YuvColorSpace, YuvData}; use app_units::Au; -use fnv::FnvHasher; use frame::FrameId; use gpu_cache::GpuCache; -use internal_types::HardwareCompositeOp; +use internal_types::{FastHashMap, HardwareCompositeOp}; use mask_cache::{ClipMode, ClipRegion, ClipSource, MaskCacheInfo}; use plane_split::{BspSplitter, Polygon, Splitter}; use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind}; @@ -28,8 +27,6 @@ use resource_cache::ResourceCache; use clip_scroll_node::{ClipInfo, ClipScrollNode, NodeType}; use clip_scroll_tree::ClipScrollTree; use std::{cmp, f32, i32, mem, usize}; -use std::collections::HashMap; -use std::hash::BuildHasherDefault; use euclid::{SideOffsets2D, vec2, vec3}; use tiling::{ContextIsolation, StackingContextIndex}; use tiling::{ClipScrollGroup, ClipScrollGroupIndex, CompositeOps, DisplayListMap, Frame}; @@ -118,9 +115,8 @@ pub struct FrameBuilder { stacking_context_store: Vec, clip_scroll_group_store: Vec, - clip_scroll_group_indices: HashMap>, + clip_scroll_group_indices: FastHashMap, packed_layers: Vec, // A stack of the current text-shadow primitives. @@ -151,7 +147,7 @@ impl FrameBuilder { FrameBuilder { stacking_context_store: recycle_vec(prev.stacking_context_store), clip_scroll_group_store: recycle_vec(prev.clip_scroll_group_store), - clip_scroll_group_indices: HashMap::default(), + clip_scroll_group_indices: FastHashMap::default(), cmds: recycle_vec(prev.cmds), packed_layers: recycle_vec(prev.packed_layers), shadow_prim_stack: recycle_vec(prev.shadow_prim_stack), @@ -169,7 +165,7 @@ impl FrameBuilder { FrameBuilder { stacking_context_store: Vec::new(), clip_scroll_group_store: Vec::new(), - clip_scroll_group_indices: HashMap::default(), + clip_scroll_group_indices: FastHashMap::default(), cmds: Vec::new(), packed_layers: Vec::new(), shadow_prim_stack: Vec::new(), @@ -908,9 +904,15 @@ impl FrameBuilder { // Shadows never use subpixel AA, but need to respect the alpha/mono flag // for reftests. - let shadow_render_mode = match self.config.default_font_render_mode { - FontRenderMode::Subpixel | FontRenderMode::Alpha => FontRenderMode::Alpha, - FontRenderMode::Mono => FontRenderMode::Mono, + let (shadow_render_mode, subpx_dir) = match self.config.default_font_render_mode { + FontRenderMode::Subpixel | FontRenderMode::Alpha => { + // TODO(gw): Expose subpixel direction in API once WR supports + // vertical text runs. + (FontRenderMode::Alpha, SubpixelDirection::Horizontal) + } + FontRenderMode::Mono => { + (FontRenderMode::Mono, SubpixelDirection::None) + } }; let prim = TextRunPrimitiveCpu { @@ -918,12 +920,14 @@ impl FrameBuilder { logical_font_size: size, glyph_range, glyph_count, - glyph_instances: Vec::new(), + glyph_gpu_blocks: Vec::new(), + glyph_keys: Vec::new(), glyph_options, normal_render_mode, shadow_render_mode, offset: run_offset, color: *color, + subpx_dir, }; // Text shadows that have a blur radius of 0 need to be rendered as normal @@ -1363,7 +1367,7 @@ impl FrameBuilder { // The stacking contexts that fall into this category are // - ones with `ContextIsolation::Items`, for their actual items to be backed // - immediate children of `ContextIsolation::Items` - let mut preserve_3d_map: HashMap = HashMap::new(); + let mut preserve_3d_map: FastHashMap = FastHashMap::default(); // The plane splitter stack, using a simple BSP tree. let mut splitter_stack = Vec::new(); diff --git a/gfx/webrender/src/glyph_cache.rs b/gfx/webrender/src/glyph_cache.rs new file mode 100644 index 000000000000..bec7209aa916 --- /dev/null +++ b/gfx/webrender/src/glyph_cache.rs @@ -0,0 +1,104 @@ +/* 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 api::{FontInstanceKey, GlyphKey}; +use frame::FrameId; +use gpu_cache::GpuCache; +use internal_types::FastHashMap; +use resource_cache::{Resource, ResourceClassCache}; +use texture_cache::{TextureCache, TextureCacheItemId}; + +pub struct CachedGlyphInfo { + pub texture_cache_id: Option, + pub last_access: FrameId, +} + +impl Resource for CachedGlyphInfo { + fn free(&self, texture_cache: &mut TextureCache) { + if let Some(id) = self.texture_cache_id { + texture_cache.free(id); + } + } + fn get_last_access_time(&self) -> FrameId { + self.last_access + } + fn set_last_access_time(&mut self, frame_id: FrameId) { + self.last_access = frame_id; + } + fn add_to_gpu_cache(&self, + texture_cache: &mut TextureCache, + gpu_cache: &mut GpuCache) { + if let Some(texture_cache_id) = self.texture_cache_id { + let item = texture_cache.get_mut(texture_cache_id); + if let Some(mut request) = gpu_cache.request(&mut item.uv_rect_handle) { + request.push(item.uv_rect); + request.push([item.user_data[0], item.user_data[1], 0.0, 0.0]); + } + } + } +} + +pub type GlyphKeyCache = ResourceClassCache; + +pub struct GlyphCache { + pub glyph_key_caches: FastHashMap, +} + +impl GlyphCache { + pub fn new() -> GlyphCache { + GlyphCache { + glyph_key_caches: FastHashMap::default(), + } + } + + pub fn get_glyph_key_cache_for_font_mut(&mut self, + font: FontInstanceKey) -> &mut GlyphKeyCache { + self.glyph_key_caches + .entry(font) + .or_insert(ResourceClassCache::new()) + } + + pub fn get_glyph_key_cache_for_font(&self, + font: &FontInstanceKey) -> &GlyphKeyCache { + self.glyph_key_caches + .get(font) + .expect("BUG: Unable to find glyph key cache!") + } + + pub fn update(&mut self, + texture_cache: &mut TextureCache, + gpu_cache: &mut GpuCache, + current_frame_id: FrameId, + expiry_frame_id: FrameId) { + let mut caches_to_remove = Vec::new(); + + for (font, glyph_key_cache) in &mut self.glyph_key_caches { + glyph_key_cache.update(texture_cache, + gpu_cache, + current_frame_id, + expiry_frame_id); + + if glyph_key_cache.is_empty() { + caches_to_remove.push(font.clone()); + } + } + + for key in caches_to_remove { + self.glyph_key_caches.remove(&key).unwrap(); + } + } + + pub fn clear_fonts(&mut self, texture_cache: &mut TextureCache, key_fun: F) + where for<'r> F: Fn(&'r &FontInstanceKey) -> bool + { + let caches_to_destroy = self.glyph_key_caches.keys() + .filter(&key_fun) + .cloned() + .collect::>(); + for key in caches_to_destroy { + let mut cache = self.glyph_key_caches.remove(&key).unwrap(); + cache.clear(texture_cache); + } + } +} diff --git a/gfx/webrender/src/glyph_rasterizer.rs b/gfx/webrender/src/glyph_rasterizer.rs index 00d09b3d9578..80fe00f1bb52 100644 --- a/gfx/webrender/src/glyph_rasterizer.rs +++ b/gfx/webrender/src/glyph_rasterizer.rs @@ -5,28 +5,24 @@ #[cfg(test)] use app_units::Au; use device::TextureFilter; -use fnv::FnvHasher; use frame::FrameId; +use glyph_cache::{CachedGlyphInfo, GlyphCache}; +use internal_types::FastHashSet; use platform::font::{FontContext, RasterizedGlyph}; use profiler::TextureCacheProfileCounters; use rayon::ThreadPool; use rayon::prelude::*; -use resource_cache::ResourceClassCache; -use std::hash::BuildHasherDefault; use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::collections::hash_map::Entry; -use std::collections::HashSet; use std::mem; -use texture_cache::{TextureCacheItemId, TextureCache}; +use texture_cache::TextureCache; #[cfg(test)] -use api::{ColorF, FontRenderMode, IdNamespace}; -use api::{FontInstanceKey, LayoutPoint}; +use api::{ColorF, LayoutPoint, FontRenderMode, IdNamespace, SubpixelDirection}; +use api::{FontInstanceKey}; use api::{FontKey, FontTemplate}; use api::{ImageData, ImageDescriptor, ImageFormat}; -use api::{GlyphKey, GlyphInstance, GlyphDimensions}; - -pub type GlyphCache = ResourceClassCache>; +use api::{GlyphKey, GlyphDimensions}; pub struct FontContexts { // These worker are mostly accessed from their corresponding worker threads. @@ -79,17 +75,17 @@ pub struct GlyphRasterizer { workers: Arc, font_contexts: Arc, - // Receives the rendered glyphs. - glyph_rx: Receiver>, - glyph_tx: Sender>, - // Maintain a set of glyphs that have been requested this // frame. This ensures the glyph thread won't rasterize // the same glyph more than once in a frame. This is required // because the glyph cache hash table is not updated // until the end of the frame when we wait for glyph requests // to be resolved. - pending_glyphs: HashSet, + pending_glyphs: FastHashSet, + + // Receives the rendered glyphs. + glyph_rx: Receiver>, + glyph_tx: Sender>, // We defer removing fonts to the end of the frame so that: // - this work is done outside of the critical path, @@ -117,9 +113,9 @@ impl GlyphRasterizer { workers: Arc::clone(&workers), } ), + pending_glyphs: FastHashSet::default(), glyph_rx, glyph_tx, - pending_glyphs: HashSet::new(), workers, fonts_to_remove: Vec::new(), } @@ -151,29 +147,20 @@ impl GlyphRasterizer { glyph_cache: &mut GlyphCache, current_frame_id: FrameId, font: FontInstanceKey, - glyph_instances: &[GlyphInstance], - requested_items: &mut HashSet>, - ) { + glyph_keys: &[GlyphKey]) { assert!(self.font_contexts.lock_shared_context().has_font(&font.font_key)); + let mut glyphs = Vec::new(); - let mut glyphs = Vec::with_capacity(glyph_instances.len()); + let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(font.clone()); // select glyphs that have not been requested yet. - for glyph in glyph_instances { - let glyph_request = GlyphRequest::new(font.clone(), - glyph.index, - glyph.point); - - match glyph_cache.entry(glyph_request.clone(), current_frame_id) { - Entry::Occupied(entry) => { - if let &Some(texture_cache_item_id) = entry.get() { - requested_items.insert(texture_cache_item_id); - } - } + for key in glyph_keys { + match glyph_key_cache.entry(key.clone(), current_frame_id) { + Entry::Occupied(..) => {} Entry::Vacant(..) => { - if !self.pending_glyphs.contains(&glyph_request) { - self.pending_glyphs.insert(glyph_request.clone()); - glyphs.push(glyph_request.clone()); + let request = GlyphRequest::new(&font, key); + if self.pending_glyphs.insert(request.clone()) { + glyphs.push(request); } } } @@ -225,12 +212,12 @@ impl GlyphRasterizer { current_frame_id: FrameId, glyph_cache: &mut GlyphCache, texture_cache: &mut TextureCache, - requested_items: &mut HashSet>, texture_cache_profile: &mut TextureCacheProfileCounters, ) { let mut rasterized_glyphs = Vec::with_capacity(self.pending_glyphs.len()); // Pull rasterized glyphs from the queue. + while !self.pending_glyphs.is_empty() { // TODO: rather than blocking until all pending glyphs are available // we could try_recv and steal work from the thread pool to take advantage @@ -271,14 +258,18 @@ impl GlyphRasterizer { [glyph.left, glyph.top], texture_cache_profile, ); - requested_items.insert(image_id); Some(image_id) } else { None } ); - glyph_cache.insert(job.request, image_id, current_frame_id); + let glyph_key_cache = glyph_cache.get_glyph_key_cache_for_font_mut(job.request.font); + + glyph_key_cache.insert(job.request.key, CachedGlyphInfo { + texture_cache_id: image_id, + last_access: current_frame_id, + }); } // Now that we are done with the critical path (rendering the glyphs), @@ -321,13 +312,10 @@ pub struct GlyphRequest { } impl GlyphRequest { - pub fn new( - font: FontInstanceKey, - index: u32, - point: LayoutPoint) -> Self { + pub fn new(font: &FontInstanceKey, key: &GlyphKey) -> Self { GlyphRequest { - key: GlyphKey::new(index, point, font.render_mode), - font, + key: key.clone(), + font: font.clone(), } } } @@ -349,7 +337,6 @@ fn raterize_200_glyphs() { let workers = Arc::new(ThreadPool::new(Configuration::new()).unwrap()); let mut glyph_rasterizer = GlyphRasterizer::new(workers); let mut glyph_cache = GlyphCache::new(); - let mut requested_items = HashSet::default(); let mut font_file = File::open("../wrench/reftests/text/VeraBd.ttf").expect("Couldn't open font file"); let mut font_data = vec![]; @@ -360,29 +347,26 @@ fn raterize_200_glyphs() { let frame_id = FrameId(1); - let mut glyph_instances = Vec::with_capacity(200); - for i in 0..200 { - glyph_instances.push(GlyphInstance { - index: i, // It doesn't matter which glyphs we are actually rendering. - point: LayoutPoint::new(0.0, 0.0), - }); - } - let font = FontInstanceKey { font_key, color: ColorF::new(0.0, 0.0, 0.0, 1.0).into(), size: Au::from_px(32), render_mode: FontRenderMode::Subpixel, glyph_options: None, + subpx_dir: SubpixelDirection::Horizontal, }; + let mut glyph_keys = Vec::with_capacity(200); + for i in 0..200 { + glyph_keys.push(GlyphKey::new(i, LayoutPoint::zero(), font.render_mode, font.subpx_dir)); + } + for i in 0..4 { glyph_rasterizer.request_glyphs( &mut glyph_cache, frame_id, font.clone(), - &glyph_instances[(50 * i)..(50 * (i + 1))], - &mut requested_items, + &glyph_keys[(50 * i)..(50 * (i + 1))], ); } @@ -392,7 +376,6 @@ fn raterize_200_glyphs() { frame_id, &mut glyph_cache, &mut TextureCache::new(4096), - &mut requested_items, &mut TextureCacheProfileCounters::new(), ); } diff --git a/gfx/webrender/src/internal_types.rs b/gfx/webrender/src/internal_types.rs index 01612f93da3e..20422b1f890f 100644 --- a/gfx/webrender/src/internal_types.rs +++ b/gfx/webrender/src/internal_types.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use device::TextureFilter; -use fnv::FnvHasher; +use fxhash::FxHasher; use profiler::BackendProfileCounters; use std::collections::{HashMap, HashSet}; use std::f32; @@ -13,8 +13,12 @@ use std::path::PathBuf; use std::sync::Arc; use tiling; use renderer::BlendMode; -use api::{ClipId, ColorU, DeviceUintRect, Epoch, ExternalImageData, ExternalImageId}; -use api::{DevicePoint, ImageData, ImageFormat, PipelineId}; +use api::{ClipId, DevicePoint, DeviceUintRect, DocumentId, Epoch}; +use api::{ExternalImageData, ExternalImageId}; +use api::{ImageData, ImageFormat, PipelineId}; + +pub type FastHashMap = HashMap>; +pub type FastHashSet = HashSet>; // An ID for a texture that is owned by the // texture cache module. This can include atlases @@ -92,84 +96,6 @@ impl BatchTextures { // In some places we need to temporarily bind a texture to any slot. pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0; -#[derive(Clone, Copy, Debug)] -pub enum VertexAttribute { - // vertex-frequency basic attributes - Position, - Color, - ColorTexCoord, - // instance-frequency primitive attributes - Data0, - Data1, -} - -#[derive(Clone, Copy, Debug)] -pub enum BlurAttribute { - // vertex frequency - Position, - // instance frequency - RenderTaskIndex, - SourceTaskIndex, - Direction, -} - -#[derive(Clone, Copy, Debug)] -pub enum ClipAttribute { - // vertex frequency - Position, - // instance frequency - RenderTaskIndex, - LayerIndex, - DataIndex, - SegmentIndex, - ResourceAddress, -} - -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct PackedVertex { - pub pos: [f32; 2], -} - -#[derive(Debug)] -#[repr(C)] -pub struct DebugFontVertex { - pub x: f32, - pub y: f32, - pub color: ColorU, - pub u: f32, - pub v: f32, -} - -impl DebugFontVertex { - pub fn new(x: f32, y: f32, u: f32, v: f32, color: ColorU) -> DebugFontVertex { - DebugFontVertex { - x, - y, - color, - u, - v, - } - } -} - -#[repr(C)] -pub struct DebugColorVertex { - pub x: f32, - pub y: f32, - pub color: ColorU, -} - -impl DebugColorVertex { - pub fn new(x: f32, y: f32, color: ColorU) -> DebugColorVertex { - DebugColorVertex { - x, - y, - color, - } - } -} - #[derive(Copy, Clone, Debug, PartialEq)] pub enum RenderTargetMode { None, @@ -241,16 +167,16 @@ pub struct RendererFrame { /// The last rendered epoch for each pipeline present in the frame. /// This information is used to know if a certain transformation on the layout has /// been rendered, which is necessary for reftests. - pub pipeline_epoch_map: HashMap>, + pub pipeline_epoch_map: FastHashMap, /// The layers that are currently affected by the over-scrolling animation. - pub layers_bouncing_back: HashSet>, + pub layers_bouncing_back: FastHashSet, pub frame: Option, } impl RendererFrame { - pub fn new(pipeline_epoch_map: HashMap>, - layers_bouncing_back: HashSet>, + pub fn new(pipeline_epoch_map: FastHashMap, + layers_bouncing_back: FastHashSet, frame: Option) -> RendererFrame { RendererFrame { @@ -263,7 +189,7 @@ impl RendererFrame { pub enum ResultMsg { RefreshShader(PathBuf), - NewFrame(RendererFrame, TextureUpdateList, BackendProfileCounters), + NewFrame(DocumentId, RendererFrame, TextureUpdateList, BackendProfileCounters), } #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)] diff --git a/gfx/webrender/src/lib.rs b/gfx/webrender/src/lib.rs index fdc4648f343f..d57a89b68bf7 100644 --- a/gfx/webrender/src/lib.rs +++ b/gfx/webrender/src/lib.rs @@ -2,39 +2,43 @@ * 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/. */ -//! A GPU based renderer for the web. -//! -//! It serves as an experimental render backend for [Servo](https://servo.org/), -//! but it can also be used as such in a standalone application. -//! -//! # External dependencies -//! WebRender currently depends on [FreeType](https://www.freetype.org/) -//! -//! # Api Structure -//! The main entry point to WebRender is the `webrender::renderer::Renderer`. -//! -//! By calling `Renderer::new(...)` you get a `Renderer`, as well as a `RenderApiSender`. -//! Your `Renderer` is responsible to render the previously processed frames onto the screen. -//! -//! By calling `yourRenderApiSenderInstance.create_api()`, you'll get a `RenderApi` instance, -//! which is responsible for the processing of new frames. A worker thread is used internally to -//! untie the workload from the application thread and therefore be able -//! to make better use of multicore systems. -//! -//! What is referred to as a `frame`, is the current geometry on the screen. -//! A new Frame is created by calling [`set_display_list()`][newframe] on the `RenderApi`. -//! When the geometry is processed, the application will be informed via a `RenderNotifier`, -//! a callback which you employ with [set_render_notifier][notifier] on the `Renderer` -//! More information about [stacking contexts][stacking_contexts]. -//! -//! `set_display_list()` also needs to be supplied with `BuiltDisplayList`s. -//! These are obtained by finalizing a `DisplayListBuilder`. These are used to draw your geometry. -//! But it doesn't only contain trivial geometry, it can also store another StackingContext, as -//! they're nestable. -//! -//! [stacking_contexts]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context -//! [newframe]: ../webrender_api/struct.RenderApi.html#method.set_display_list -//! [notifier]: renderer/struct.Renderer.html#method.set_render_notifier +/*! +A GPU based renderer for the web. + +It serves as an experimental render backend for [Servo](https://servo.org/), +but it can also be used as such in a standalone application. + +# External dependencies +WebRender currently depends on [FreeType](https://www.freetype.org/) + +# Api Structure +The main entry point to WebRender is the `webrender::renderer::Renderer`. + +By calling `Renderer::new(...)` you get a `Renderer`, as well as a `RenderApiSender`. +Your `Renderer` is responsible to render the previously processed frames onto the screen. + +By calling `yourRenderApiSender.create_api()`, you'll get a `RenderApi` instance, +which is responsible for managing resources and documents. A worker thread is used internally +to untie the workload from the application thread and therefore be able to make better use of +multicore systems. + +## Frame + +What is referred to as a `frame`, is the current geometry on the screen. +A new Frame is created by calling [`set_display_list()`][newframe] on the `RenderApi`. +When the geometry is processed, the application will be informed via a `RenderNotifier`, +a callback which you employ with [set_render_notifier][notifier] on the `Renderer` +More information about [stacking contexts][stacking_contexts]. + +`set_display_list()` also needs to be supplied with `BuiltDisplayList`s. +These are obtained by finalizing a `DisplayListBuilder`. These are used to draw your geometry. +But it doesn't only contain trivial geometry, it can also store another StackingContext, as +they're nestable. + +[stacking_contexts]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context +[newframe]: ../webrender_api/struct.RenderApi.html#method.set_display_list +[notifier]: renderer/struct.Renderer.html#method.set_render_notifier +*/ #[macro_use] extern crate lazy_static; @@ -57,6 +61,7 @@ mod frame; mod frame_builder; mod freelist; mod geometry; +mod glyph_cache; mod glyph_rasterizer; mod gpu_cache; mod internal_types; @@ -128,7 +133,7 @@ extern crate dwrote; extern crate app_units; extern crate bincode; extern crate euclid; -extern crate fnv; +extern crate fxhash; extern crate gleam; extern crate num_traits; //extern crate notify; diff --git a/gfx/webrender/src/platform/macos/font.rs b/gfx/webrender/src/platform/macos/font.rs index 070f03b9144a..e1072271ae7d 100644 --- a/gfx/webrender/src/platform/macos/font.rs +++ b/gfx/webrender/src/platform/macos/font.rs @@ -13,17 +13,17 @@ use core_graphics::geometry::{CGPoint, CGSize, CGRect}; use core_text::font::CTFont; use core_text::font_descriptor::kCTFontDefaultOrientation; use core_text; -use std::collections::HashMap; +use internal_types::FastHashMap; use std::collections::hash_map::Entry; use api::{ColorU, FontKey, FontRenderMode, GlyphDimensions}; -use api::{GlyphKey, SubpixelPoint}; +use api::{GlyphKey, SubpixelDirection}; use api::{FontInstanceKey, NativeFontHandle}; use gamma_lut::{GammaLut, Color as ColorLut}; use std::ptr; pub struct FontContext { - cg_fonts: HashMap, - ct_fonts: HashMap<(FontKey, Au), CTFont>, + cg_fonts: FastHashMap, + ct_fonts: FastHashMap<(FontKey, Au), CTFont>, gamma_lut: GammaLut, } @@ -83,7 +83,8 @@ fn supports_subpixel_aa() -> bool { fn get_glyph_metrics(ct_font: &CTFont, glyph: CGGlyph, - subpixel_point: &SubpixelPoint) -> GlyphMetrics { + x_offset: f64, + y_offset: f64) -> GlyphMetrics { let bounds = ct_font.get_bounding_rects_for_glyphs(kCTFontDefaultOrientation, &[glyph]); if bounds.origin.x.is_nan() || bounds.origin.y.is_nan() || @@ -103,8 +104,6 @@ fn get_glyph_metrics(ct_font: &CTFont, }; } - let (x_offset, y_offset) = subpixel_point.to_f64(); - // First round out to pixel boundaries // CG Origin is bottom left let mut left = bounds.origin.x.floor() as i32; @@ -154,8 +153,8 @@ impl FontContext { let gamma = 0.0; FontContext { - cg_fonts: HashMap::new(), - ct_fonts: HashMap::new(), + cg_fonts: FastHashMap::default(), + ct_fonts: FastHashMap::default(), gamma_lut: GammaLut::new(contrast, gamma, gamma), } } @@ -242,7 +241,8 @@ impl FontContext { key: &GlyphKey) -> Option { self.get_ct_font(font.font_key, font.size).and_then(|ref ct_font| { let glyph = key.index as CGGlyph; - let metrics = get_glyph_metrics(ct_font, glyph, &key.subpixel_point); + let (x_offset, y_offset) = font.get_subpx_offset(key); + let metrics = get_glyph_metrics(ct_font, glyph, x_offset, y_offset); if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 { None } else { @@ -307,7 +307,8 @@ impl FontContext { }; let glyph = key.index as CGGlyph; - let metrics = get_glyph_metrics(&ct_font, glyph, &key.subpixel_point); + let (x_offset, y_offset) = font.get_subpx_offset(key); + let metrics = get_glyph_metrics(&ct_font, glyph, x_offset, y_offset); if metrics.rasterized_width == 0 || metrics.rasterized_height == 0 { return Some(RasterizedGlyph::blank()) } @@ -365,8 +366,6 @@ impl FontContext { cg_context.set_allows_antialiasing(antialias); cg_context.set_should_antialias(antialias); - let (x_offset, y_offset) = key.subpixel_point.to_f64(); - // CG Origin is bottom left, WR is top left. Need -y offset let rasterization_origin = CGPoint { x: -metrics.rasterized_left as f64 + x_offset, @@ -440,4 +439,3 @@ impl FontContext { }) } } - diff --git a/gfx/webrender/src/platform/unix/font.rs b/gfx/webrender/src/platform/unix/font.rs index 7cf4c2bebed4..6e534fa6c5fa 100644 --- a/gfx/webrender/src/platform/unix/font.rs +++ b/gfx/webrender/src/platform/unix/font.rs @@ -2,21 +2,20 @@ * 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 app_units::Au; use api::{FontInstanceKey, FontKey, FontRenderMode, GlyphDimensions}; -use api::{NativeFontHandle}; +use api::{NativeFontHandle, SubpixelDirection}; use api::{GlyphKey}; +use internal_types::FastHashMap; -use freetype::freetype::{FT_Render_Mode, FT_Pixel_Mode}; -use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter}; -use freetype::freetype::{FT_Library, FT_Set_Char_Size}; -use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6}; +use freetype::freetype::{FT_Render_Mode, FT_Pixel_Mode, FT_BBox, FT_Outline_Translate}; +use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos}; +use freetype::freetype::{FT_Library, FT_Set_Char_Size, FT_Outline_Get_CBox}; +use freetype::freetype::{FT_Face, FT_Long, FT_UInt, FT_F26Dot6, FT_Glyph_Format}; use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph}; use freetype::freetype::{FT_New_Memory_Face, FT_GlyphSlot, FT_LcdFilter}; use freetype::freetype::{FT_Done_Face, FT_Error, FT_Int32, FT_Get_Char_Index}; -use std::{cmp, mem, ptr, slice}; -use std::collections::HashMap; +use std::{mem, ptr, slice}; // This constant is not present in the freetype // bindings due to bindgen not handling the way @@ -35,7 +34,8 @@ struct Face { pub struct FontContext { lib: FT_Library, - faces: HashMap, + faces: FastHashMap, + lcd_extra_pixels: i64, } // FreeType resources are safe to move between threads as long as they @@ -56,20 +56,27 @@ const SUCCESS: FT_Error = FT_Error(0); impl FontContext { pub fn new() -> FontContext { let mut lib: FT_Library = ptr::null_mut(); + + // Per Skia, using a filter adds one full pixel to each side. + let mut lcd_extra_pixels = 1; + unsafe { let result = FT_Init_FreeType(&mut lib); assert!(result.succeeded(), "Unable to initialize FreeType library {:?}", result); // TODO(gw): Check result of this to determine if freetype build supports subpixel. let result = FT_Library_SetLcdFilter(lib, FT_LcdFilter::FT_LCD_FILTER_DEFAULT); + if !result.succeeded() { println!("WARN: Initializing a FreeType library build without subpixel AA enabled!"); + lcd_extra_pixels = 0; } } FontContext { lib, - faces: HashMap::new(), + faces: FastHashMap::default(), + lcd_extra_pixels: lcd_extra_pixels, } } @@ -112,13 +119,12 @@ impl FontContext { } fn load_glyph(&self, - font_key: FontKey, - size: Au, - character: u32) -> Option { + font: &FontInstanceKey, + glyph: &GlyphKey) -> Option { - debug_assert!(self.faces.contains_key(&font_key)); - let face = self.faces.get(&font_key).unwrap(); - let char_size = size.to_f64_px() * 64.0 + 0.5; + debug_assert!(self.faces.contains_key(&font.font_key)); + let face = self.faces.get(&font.font_key).unwrap(); + let char_size = font.size.to_f64_px() * 64.0 + 0.5; assert_eq!(SUCCESS, unsafe { FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0) @@ -126,35 +132,99 @@ impl FontContext { let result = unsafe { FT_Load_Glyph(face.face, - character as FT_UInt, + glyph.index as FT_UInt, GLYPH_LOAD_FLAGS) }; if result == SUCCESS { let slot = unsafe { (*face.face).glyph }; assert!(slot != ptr::null_mut()); - Some(slot) + + // TODO(gw): We use the FT_Outline_* APIs to manage sub-pixel offsets. + // We will need a custom code path for bitmap fonts (which + // are very rare). + match unsafe { (*slot).format } { + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => { + Some(slot) + } + _ => { + error!("TODO: Support bitmap fonts!"); + None + } + } } else { error!("Unable to load glyph for {} of size {:?} from font {:?}, {:?}", - character, size, font_key, result); + glyph.index, font.size, font.font_key, result); None } } - fn get_glyph_dimensions_impl(slot: FT_GlyphSlot) -> Option { + // Get the bounding box for a glyph, accounting for sub-pixel positioning. + fn get_bounding_box(&self, + slot: FT_GlyphSlot, + font: &FontInstanceKey, + glyph: &GlyphKey) -> FT_BBox { + let mut cbox: FT_BBox = unsafe { mem::uninitialized() }; + + // Get the estimated bounding box from FT (control points). + unsafe { + FT_Outline_Get_CBox(&(*slot).outline, &mut cbox); + } + + // Convert the subpixel offset to floats. + let (dx, dy) = font.get_subpx_offset(glyph); + + // Apply extra pixel of padding for subpixel AA, due to the filter. + let padding = match font.render_mode { + FontRenderMode::Subpixel => self.lcd_extra_pixels * 64, + FontRenderMode::Alpha | FontRenderMode::Mono => 0, + }; + cbox.xMin -= padding as FT_Pos; + cbox.xMax += padding as FT_Pos; + + // Offset the bounding box by subpixel positioning. + // Convert to 26.6 fixed point format for FT. + match font.subpx_dir { + SubpixelDirection::None => {} + SubpixelDirection::Horizontal => { + let dx = (dx * 64.0 + 0.5) as FT_Long; + cbox.xMin += dx; + cbox.xMax += dx; + } + SubpixelDirection::Vertical => { + let dy = (dy * 64.0 + 0.5) as FT_Long; + cbox.yMin += dy; + cbox.yMax += dy; + } + } + + // Outset the box to device pixel boundaries + cbox.xMin &= !63; + cbox.yMin &= !63; + cbox.xMax = (cbox.xMax + 63) & !63; + cbox.yMax = (cbox.yMax + 63) & !63; + + cbox + } + + fn get_glyph_dimensions_impl(&self, + slot: FT_GlyphSlot, + font: &FontInstanceKey, + glyph: &GlyphKey) -> Option { let metrics = unsafe { &(*slot).metrics }; - if metrics.width == 0 || metrics.height == 0 { + + // If there's no advance, no need to consider this glyph + // for layout. + if metrics.horiAdvance == 0 { None } else { - let left = metrics.horiBearingX >> 6; - let top = metrics.horiBearingY >> 6; - let right = (metrics.horiBearingX + metrics.width + 0x3f) >> 6; - let bottom = (metrics.horiBearingY + metrics.height + 0x3f) >> 6; + let cbox = self.get_bounding_box(slot, font, glyph); + Some(GlyphDimensions { - left: left as i32, - top: top as i32, - width: (right - left) as u32, - height: (bottom - top) as u32, + left: (cbox.xMin >> 6) as i32, + top: (cbox.yMax >> 6) as i32, + width: ((cbox.xMax - cbox.xMin) >> 6) as u32, + height: ((cbox.yMax - cbox.yMin) >> 6) as u32, advance: metrics.horiAdvance as f32 / 64.0, }) } @@ -177,10 +247,10 @@ impl FontContext { pub fn get_glyph_dimensions(&mut self, font: &FontInstanceKey, key: &GlyphKey) -> Option { - self.load_glyph(font.font_key, - font.size, - key.index) - .and_then(Self::get_glyph_dimensions_impl) + let slot = self.load_glyph(font, key); + slot.and_then(|slot| { + self.get_glyph_dimensions_impl(slot, font, key) + }) } pub fn rasterize_glyph(&mut self, @@ -188,106 +258,111 @@ impl FontContext { key: &GlyphKey) -> Option { - let slot = match self.load_glyph(font.font_key, - font.size, - key.index) { + let slot = match self.load_glyph(font, key) { Some(slot) => slot, None => return None, }; + let render_mode = match font.render_mode { FontRenderMode::Mono => FT_Render_Mode::FT_RENDER_MODE_MONO, FontRenderMode::Alpha => FT_Render_Mode::FT_RENDER_MODE_NORMAL, FontRenderMode::Subpixel => FT_Render_Mode::FT_RENDER_MODE_LCD, }; + // Get dimensions of the glyph, to see if we need to rasterize it. + let dimensions = match self.get_glyph_dimensions_impl(slot, font, key) { + Some(val) => val, + None => return None, + }; + + // For spaces and other non-printable characters, early out. + if dimensions.width == 0 || dimensions.height == 0 { + return None; + } + + // Get the subpixel offsets in FT 26.6 format. + let (dx, dy) = font.get_subpx_offset(key); + let dx = (dx * 64.0 + 0.5) as FT_Long; + let dy = (dy * 64.0 + 0.5) as FT_Long; + + // Move the outline curves to be at the origin, taking + // into account the subpixel positioning. + unsafe { + let outline = &(*slot).outline; + let mut cbox: FT_BBox = mem::uninitialized(); + FT_Outline_Get_CBox(outline, &mut cbox); + FT_Outline_Translate(outline, dx - ((cbox.xMin + dx) & !63), + dy - ((cbox.yMin + dy) & !63)); + } + let result = unsafe { FT_Render_Glyph(slot, render_mode) }; if result != SUCCESS { error!("Unable to rasterize {:?} with {:?}, {:?}", key, render_mode, result); return None; } - let dimensions = match Self::get_glyph_dimensions_impl(slot) { - Some(val) => val, - None => return None, - }; - let bitmap = unsafe { &(*slot).bitmap }; let pixel_mode = unsafe { mem::transmute(bitmap.pixel_mode as u32) }; info!("Rasterizing {:?} as {:?} with dimensions {:?}", key, render_mode, dimensions); - // we may be filling only a part of the buffer, so initialize the whole thing with 0 - let mut final_buffer = Vec::with_capacity(dimensions.width as usize * - dimensions.height as usize * - 4); - let offset_x = dimensions.left - unsafe { (*slot).bitmap_left }; - let src_pixel_width = match pixel_mode { + let actual_width = match pixel_mode { FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { assert!(bitmap.width % 3 == 0); bitmap.width / 3 }, - _ => bitmap.width, - }; - // determine the destination range of texels that `bitmap` provides data for - let dst_start = cmp::max(0, -offset_x); - let dst_end = cmp::min(dimensions.width as i32, src_pixel_width as i32 - offset_x); + FT_Pixel_Mode::FT_PIXEL_MODE_MONO | + FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { + bitmap.width + } + _ => { + panic!("Unexpected pixel mode!"); + } + } as i32; - for y in 0 .. dimensions.height { - let src_y = y as i32 - dimensions.top + unsafe { (*slot).bitmap_top }; - if src_y < 0 || src_y >= bitmap.rows as i32 { - for _x in 0 .. dimensions.width { - final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]); - } - continue - } - let base = unsafe { - bitmap.buffer.offset((src_y * bitmap.pitch) as isize) + let actual_height = bitmap.rows as i32; + let top = unsafe { (*slot).bitmap_top }; + let left = unsafe { (*slot).bitmap_left }; + let mut final_buffer = vec![0; (actual_width * actual_height * 4) as usize]; + + // Extract the final glyph from FT format into RGBA8 format, which is + // what WR expects. + for y in 0..actual_height { + // Get pointer to the bytes for this row. + let mut src = unsafe { + bitmap.buffer.offset((y * bitmap.pitch) as isize) }; - for _x in 0 .. dst_start { - final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]); - } - match pixel_mode { - FT_Pixel_Mode::FT_PIXEL_MODE_MONO => { - for x in dst_start .. dst_end { - let src_x = x + offset_x; - let mask = 0x80 >> (src_x & 0x7); - let byte = unsafe { - *base.offset((src_x >> 3) as isize) - }; + + for x in 0..actual_width { + let value = match pixel_mode { + FT_Pixel_Mode::FT_PIXEL_MODE_MONO => { + let mask = 0x80 >> (x & 0x7); + let byte = unsafe { *src.offset((x >> 3) as isize) }; let alpha = if byte & mask != 0 { 0xff } else { 0 }; - final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, alpha]); + [0xff, 0xff, 0xff, alpha] } - } - FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { - for x in dst_start .. dst_end { - let alpha = unsafe { - *base.offset((x + offset_x) as isize) - }; - final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, alpha]); + FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { + let alpha = unsafe { *src }; + src = unsafe { src.offset(1) }; + [0xff, 0xff, 0xff, alpha] } - } - FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { - for x in dst_start .. dst_end { - let src_x = ((x + offset_x) * 3) as isize; - assert!(src_x+2 < bitmap.pitch as isize); - let t = unsafe { - slice::from_raw_parts(base.offset(src_x), 3) - }; - final_buffer.extend_from_slice(&[t[2], t[1], t[0], 0xff]); + FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { + let t = unsafe { slice::from_raw_parts(src, 3) }; + src = unsafe { src.offset(3) }; + [t[2], t[1], t[0], 0xff] } - } - _ => panic!("Unsupported {:?}", pixel_mode) + _ => panic!("Unsupported {:?}", pixel_mode) + }; + let i = 4 * (y * actual_width + x) as usize; + let dest = &mut final_buffer[i..i+4]; + dest.clone_from_slice(&value); } - for _x in dst_end .. dimensions.width as i32 { - final_buffer.extend_from_slice(&[0xff, 0xff, 0xff, 0]); - } - assert_eq!(final_buffer.len(), ((y+1) * dimensions.width * 4) as usize); } Some(RasterizedGlyph { - left: dimensions.left as f32, - top: dimensions.top as f32, - width: dimensions.width as u32, - height: dimensions.height as u32, + left: (dimensions.left + left) as f32, + top: (dimensions.top + top - actual_height) as f32, + width: actual_width as u32, + height: actual_height as u32, bytes: final_buffer, }) } diff --git a/gfx/webrender/src/platform/windows/font.rs b/gfx/webrender/src/platform/windows/font.rs index 2064a2032ef4..3808e89f082e 100644 --- a/gfx/webrender/src/platform/windows/font.rs +++ b/gfx/webrender/src/platform/windows/font.rs @@ -2,10 +2,10 @@ * 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 std::collections::HashMap; use api::{FontKey, FontRenderMode, GlyphDimensions}; -use api::{FontInstanceKey, GlyphKey, GlyphOptions}; +use api::{FontInstanceKey, GlyphKey, GlyphOptions, SubpixelDirection}; use gamma_lut::{GammaLut, Color as ColorLut}; +use internal_types::FastHashMap; use dwrote; @@ -19,7 +19,7 @@ lazy_static! { } pub struct FontContext { - fonts: HashMap, + fonts: FastHashMap, gamma_lut: GammaLut, gdi_gamma_lut: GammaLut, } @@ -95,7 +95,7 @@ impl FontContext { let gamma = 1.8; let gdi_gamma = 2.3; FontContext { - fonts: HashMap::new(), + fonts: FastHashMap::default(), gamma_lut: GammaLut::new(contrast, gamma, gamma), gdi_gamma_lut: GammaLut::new(contrast, gdi_gamma, gdi_gamma), } @@ -181,7 +181,7 @@ impl FontContext { dwrite_measure_mode, font.glyph_options); - let (x_offset, y_offset) = key.subpixel_point.to_f64(); + let (x_offset, y_offset) = font.get_subpx_offset(key); let transform = Some( dwrote::DWRITE_MATRIX { m11: 1.0, m12: 0.0, m21: 0.0, m22: 1.0, dx: x_offset as f32, dy: y_offset as f32 } diff --git a/gfx/webrender/src/prim_store.rs b/gfx/webrender/src/prim_store.rs index a72872661d7a..b6d28249720c 100644 --- a/gfx/webrender/src/prim_store.rs +++ b/gfx/webrender/src/prim_store.rs @@ -5,8 +5,8 @@ use api::{BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect, DeviceIntSize, DevicePoint}; use api::{ExtendMode, FontKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop}; use api::{ImageKey, ImageRendering, ItemRange, LayerPoint, LayerRect, LayerSize, TextShadow}; -use api::{LayerToWorldTransform, TileOffset, WebGLContextId, YuvColorSpace, YuvFormat}; -use api::{device_length, FontInstanceKey, LayerVector2D, LineOrientation, LineStyle}; +use api::{GlyphKey, LayerToWorldTransform, TileOffset, WebGLContextId, YuvColorSpace, YuvFormat}; +use api::{device_length, FontInstanceKey, LayerVector2D, LineOrientation, LineStyle, SubpixelDirection}; use app_units::Au; use border::BorderCornerInstance; use euclid::{Size2D}; @@ -518,12 +518,13 @@ pub struct TextRunPrimitiveCpu { pub logical_font_size: Au, pub glyph_range: ItemRange, pub glyph_count: usize, - // TODO(gw): Maybe make this an Arc for sharing with resource cache - pub glyph_instances: Vec, + pub glyph_keys: Vec, + pub glyph_gpu_blocks: Vec, pub glyph_options: Option, pub normal_render_mode: FontRenderMode, pub shadow_render_mode: FontRenderMode, pub color: ColorF, + pub subpx_dir: SubpixelDirection, } #[derive(Debug, Copy, Clone)] @@ -538,20 +539,6 @@ impl TextRunPrimitiveCpu { device_pixel_ratio: f32, display_list: &BuiltDisplayList, run_mode: TextRunMode) { - // Cache the glyph positions, if not in the cache already. - // TODO(gw): In the future, remove `glyph_instances` - // completely, and just reference the glyphs - // directly from the displaty list. - if self.glyph_instances.is_empty() { - let src_glyphs = display_list.get(self.glyph_range); - for src in src_glyphs { - self.glyph_instances.push(GlyphInstance { - index: src.index, - point: src.point, - }); - } - } - let font_size_dp = self.logical_font_size.scale_by(device_pixel_ratio); let render_mode = match run_mode { TextRunMode::Normal => self.normal_render_mode, @@ -562,28 +549,58 @@ impl TextRunPrimitiveCpu { font_size_dp, self.color, render_mode, - self.glyph_options); + self.glyph_options, + self.subpx_dir); - resource_cache.request_glyphs(font, &self.glyph_instances); + // Cache the glyph positions, if not in the cache already. + // TODO(gw): In the future, remove `glyph_instances` + // completely, and just reference the glyphs + // directly from the display list. + if self.glyph_keys.is_empty() { + let src_glyphs = display_list.get(self.glyph_range); + + // TODO(gw): If we support chunks() on AuxIter + // in the future, this code below could + // be much simpler... + let mut gpu_block = GpuBlockData::empty(); + + for (i, src) in src_glyphs.enumerate() { + let key = GlyphKey::new(src.index, + src.point, + font.render_mode, + font.subpx_dir); + self.glyph_keys.push(key); + + // Two glyphs are packed per GPU block. + + if (i & 1) == 0 { + gpu_block.data[0] = src.point.x; + gpu_block.data[1] = src.point.y; + } else { + gpu_block.data[2] = src.point.x; + gpu_block.data[3] = src.point.y; + self.glyph_gpu_blocks.push(gpu_block); + } + } + + // Ensure the last block is added in the case + // of an odd number of glyphs. + if (self.glyph_keys.len() & 1) != 0 { + self.glyph_gpu_blocks.push(gpu_block); + } + } + + resource_cache.request_glyphs(font, &self.glyph_keys); } fn write_gpu_blocks(&self, request: &mut GpuDataRequest) { request.push(self.color); - request.push([self.offset.x, self.offset.y, 0.0, 0.0]); - - // Two glyphs are packed per GPU block. - for glyph_chunk in self.glyph_instances.chunks(2) { - // In the case of an odd number of glyphs, the - // last glyph will get duplicated in the final - // GPU block. - let first_glyph = glyph_chunk.first().unwrap(); - let second_glyph = glyph_chunk.last().unwrap(); - request.push([first_glyph.point.x, - first_glyph.point.y, - second_glyph.point.x, - second_glyph.point.y]); - } + request.push([self.offset.x, + self.offset.y, + self.subpx_dir as u32 as f32, + 0.0]); + request.extend_from_slice(&self.glyph_gpu_blocks); } } diff --git a/gfx/webrender/src/profiler.rs b/gfx/webrender/src/profiler.rs index f632c0488b7f..aaebbb229a4d 100644 --- a/gfx/webrender/src/profiler.rs +++ b/gfx/webrender/src/profiler.rs @@ -131,6 +131,18 @@ pub struct TimeProfileCounter { invert: bool, } +pub struct Timer<'a> { + start: u64, + result: &'a mut u64, +} + +impl<'a> Drop for Timer<'a> { + fn drop(&mut self) { + let end = precise_time_ns(); + *self.result += end - self.start; + } +} + impl TimeProfileCounter { pub fn new(description: &'static str, invert: bool) -> TimeProfileCounter { TimeProfileCounter { @@ -158,6 +170,13 @@ impl TimeProfileCounter { val } + pub fn timer(&mut self) -> Timer { + Timer { + start: precise_time_ns(), + result: &mut self.nanoseconds, + } + } + pub fn inc(&mut self, ns: u64) { self.nanoseconds += ns; } diff --git a/gfx/webrender/src/record.rs b/gfx/webrender/src/record.rs index 67c331d014ff..5c6c7b996537 100644 --- a/gfx/webrender/src/record.rs +++ b/gfx/webrender/src/record.rs @@ -64,19 +64,11 @@ impl ApiRecordingReceiver for BinaryRecorder { pub fn should_record_msg(msg: &ApiMsg) -> bool { match *msg { - ApiMsg::AddRawFont(..) | - ApiMsg::AddNativeFont(..) | - ApiMsg::DeleteFont(..) | - ApiMsg::AddImage(..) | - ApiMsg::GenerateFrame(..) | - ApiMsg::UpdateImage(..) | - ApiMsg::DeleteImage(..) | - ApiMsg::SetDisplayList(..) | - ApiMsg::SetRootPipeline(..) | - ApiMsg::Scroll(..) | - ApiMsg::TickScrollingBounce | - ApiMsg::WebGLCommand(..) | - ApiMsg::SetWindowParameters(..) => + ApiMsg::UpdateResources(..) | + ApiMsg::AddDocument{..} | + ApiMsg::UpdateDocument(..) | + ApiMsg::DeleteDocument(..) | + ApiMsg::WebGLCommand(..) => true, _ => false } diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs index 6fd369fa0274..5f5f866fa87d 100644 --- a/gfx/webrender/src/render_backend.rs +++ b/gfx/webrender/src/render_backend.rs @@ -5,12 +5,11 @@ use frame::Frame; use frame_builder::FrameBuilderConfig; use gpu_cache::GpuCache; -use internal_types::{SourceTexture, ResultMsg, RendererFrame}; -use profiler::{BackendProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters}; +use internal_types::{FastHashMap, SourceTexture, ResultMsg, RendererFrame}; +use profiler::{BackendProfileCounters, ResourceProfileCounters}; use record::ApiRecordingReceiver; use resource_cache::ResourceCache; use scene::Scene; -use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::sync::mpsc::Sender; use texture_cache::TextureCache; @@ -21,10 +20,9 @@ use webgl_types::{GLContextHandleWrapper, GLContextWrapper}; use api::channel::{MsgReceiver, PayloadReceiver, PayloadReceiverHelperMethods}; use api::channel::{PayloadSender, PayloadSenderHelperMethods}; use api::{ApiMsg, BlobImageRenderer, BuiltDisplayList, DeviceIntPoint}; -use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, IdNamespace, ImageData}; -use api::{LayerPoint, PipelineId, RenderDispatcher, RenderNotifier}; +use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentId, DocumentMsg}; +use api::{IdNamespace, LayerPoint, RenderDispatcher, RenderNotifier}; use api::{VRCompositorCommand, VRCompositorHandler, WebGLCommand, WebGLContextId}; -use api::{FontTemplate}; #[cfg(feature = "webgl")] use offscreen_gl_context::GLContextDispatcher; @@ -32,6 +30,138 @@ use offscreen_gl_context::GLContextDispatcher; #[cfg(not(feature = "webgl"))] use webgl_types::GLContextDispatcher; +struct Document { + scene: Scene, + frame: Frame, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + pan: DeviceIntPoint, + page_zoom_factor: f32, + pinch_zoom_factor: f32, + // A helper switch to prevent any frames rendering triggered by scrolling + // messages between `SetDisplayList` and `GenerateFrame`. + // If we allow them, then a reftest that scrolls a few layers before generating + // the first frame would produce inconsistent rendering results, because + // scroll events are not necessarily received in deterministic order. + render_on_scroll: Option, +} + +impl Document { + pub fn new( + config: FrameBuilderConfig, + initial_size: DeviceUintSize, + enable_render_on_scroll: bool, + ) -> Self { + let render_on_scroll = if enable_render_on_scroll { + Some(false) + } else { + None + }; + Document { + scene: Scene::new(), + frame: Frame::new(config), + window_size: initial_size, + inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_size), + pan: DeviceIntPoint::zero(), + page_zoom_factor: 1.0, + pinch_zoom_factor: 1.0, + render_on_scroll, + } + } + + fn accumulated_scale_factor(&self, hidpi_factor: f32) -> f32 { + hidpi_factor * self.page_zoom_factor * self.pinch_zoom_factor + } + + fn build_scene(&mut self, resource_cache: &mut ResourceCache, hidpi_factor: f32) { + let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor); + self.frame.create(&self.scene, + resource_cache, + self.window_size, + self.inner_rect, + accumulated_scale_factor); + } + + fn render(&mut self, + resource_cache: &mut ResourceCache, + gpu_cache: &mut GpuCache, + resource_profile: &mut ResourceProfileCounters, + hidpi_factor: f32, + )-> RendererFrame { + let accumulated_scale_factor = self.accumulated_scale_factor(hidpi_factor); + let pan = LayerPoint::new(self.pan.x as f32 / accumulated_scale_factor, + self.pan.y as f32 / accumulated_scale_factor); + self.frame.build(resource_cache, + gpu_cache, + &self.scene.display_lists, + accumulated_scale_factor, + pan, + &mut resource_profile.texture_cache, + &mut resource_profile.gpu_cache) + } +} + +struct WebGL { + last_id: WebGLContextId, + contexts: FastHashMap, + active_id: Option, +} + +impl WebGL { + fn new() -> Self { + WebGL { + last_id: WebGLContextId(0), + contexts: FastHashMap::default(), + active_id: None, + } + } + + fn register(&mut self, context: GLContextWrapper) -> WebGLContextId { + // Creating a new GLContext may make the current bound context_id dirty. + // Clear it to ensure that make_current() is called in subsequent commands. + self.active_id = None; + self.last_id.0 += 1; + self.contexts.insert(self.last_id, context); + self.last_id + } + + fn activate(&mut self, id: WebGLContextId) -> &mut GLContextWrapper { + let ctx = self.contexts.get_mut(&id).unwrap(); + if Some(id) != self.active_id { + ctx.make_current(); + self.active_id = Some(id); + } + ctx + } + + fn flush(&mut self) { + if let Some(id) = self.active_id.take() { + self.contexts[&id].unbind(); + } + + // When running in OSMesa mode with texture sharing, + // a flush is required on any GL contexts to ensure + // that read-back from the shared texture returns + // valid data! This should be fine to have run on all + // implementations - a single flush for each webgl + // context at the start of a render frame should + // incur minimal cost. + for (_, context) in &self.contexts { + context.make_current(); + context.apply_command(WebGLCommand::Flush); + context.unbind(); + } + } +} + +enum DocumentOp { + Nop, + Built, + ScrolledNop, + Scrolled(RendererFrame), + Rendered(RendererFrame), +} + /// The render backend is responsible for transforming high level display lists into /// GPU-friendly work which is then submitted to the renderer in the form of a frame::Frame. /// @@ -44,59 +174,48 @@ pub struct RenderBackend { // TODO(gw): Consider using strongly typed units here. hidpi_factor: f32, - page_zoom_factor: f32, - pinch_zoom_factor: f32, - pan: DeviceIntPoint, - window_size: DeviceUintSize, - inner_rect: DeviceUintRect, next_namespace_id: IdNamespace, gpu_cache: GpuCache, resource_cache: ResourceCache, - scene: Scene, - frame: Frame, + frame_config: FrameBuilderConfig, + documents: FastHashMap, notifier: Arc>>>, webrender_context_handle: Option, - webgl_contexts: HashMap, - current_bound_webgl_context_id: Option, recorder: Option>, main_thread_dispatcher: Arc>>>, - next_webgl_id: usize, - vr_compositor_handler: Arc>>>, + webgl: WebGL, enable_render_on_scroll: bool, - - // A helper switch to prevent any frames rendering triggered by scrolling - // messages between `SetDisplayList` and `GenerateFrame`. - // If we allow them, then a reftest that scrolls a few layers before generating - // the first frame would produce inconsistent rendering results, because - // scroll events are not necessarily received in deterministic order. - render_on_scroll: bool, } impl RenderBackend { - pub fn new(api_rx: MsgReceiver, - payload_rx: PayloadReceiver, - payload_tx: PayloadSender, - result_tx: Sender, - hidpi_factor: f32, - texture_cache: TextureCache, - workers: Arc, - notifier: Arc>>>, - webrender_context_handle: Option, - config: FrameBuilderConfig, - recorder: Option>, - main_thread_dispatcher: Arc>>>, - blob_image_renderer: Option>, - vr_compositor_handler: Arc>>>, - initial_window_size: DeviceUintSize, - enable_render_on_scroll: bool) -> RenderBackend { + pub fn new( + api_rx: MsgReceiver, + payload_rx: PayloadReceiver, + payload_tx: PayloadSender, + result_tx: Sender, + hidpi_factor: f32, + texture_cache: TextureCache, + workers: Arc, + notifier: Arc>>>, + webrender_context_handle: Option, + frame_config: FrameBuilderConfig, + recorder: Option>, + main_thread_dispatcher: Arc>>>, + blob_image_renderer: Option>, + vr_compositor_handler: Arc>>>, + enable_render_on_scroll: bool, + ) -> RenderBackend { - let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer); + let resource_cache = ResourceCache::new(texture_cache, + workers, + blob_image_renderer, + frame_config.cache_expiry_frames); register_thread_with_profiler("Backend".to_string()); @@ -106,37 +225,214 @@ impl RenderBackend { payload_tx, result_tx, hidpi_factor, - page_zoom_factor: 1.0, - pinch_zoom_factor: 1.0, - pan: DeviceIntPoint::zero(), + resource_cache, gpu_cache: GpuCache::new(), - scene: Scene::new(), - frame: Frame::new(config), + frame_config, + documents: FastHashMap::default(), next_namespace_id: IdNamespace(1), notifier, webrender_context_handle, - webgl_contexts: HashMap::new(), - current_bound_webgl_context_id: None, recorder, main_thread_dispatcher, - next_webgl_id: 0, + vr_compositor_handler, - window_size: initial_window_size, - inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_window_size), + webgl: WebGL::new(), + enable_render_on_scroll, - render_on_scroll: false, } } - fn scroll_frame(&mut self, frame_maybe: Option, - profile_counters: &mut BackendProfileCounters) { - match frame_maybe { - Some(frame) => { - self.publish_frame(frame, profile_counters); - self.notify_compositor_of_new_scroll_frame(true) + fn process_document(&mut self, document_id: DocumentId, message: DocumentMsg, + frame_counter: u32, mut profile_counters: &mut BackendProfileCounters) + -> DocumentOp + { + let doc = self.documents.get_mut(&document_id).expect("No document?"); + + match message { + DocumentMsg::SetPageZoom(factor) => { + doc.page_zoom_factor = factor.get(); + DocumentOp::Nop + } + DocumentMsg::SetPinchZoom(factor) => { + doc.pinch_zoom_factor = factor.get(); + DocumentOp::Nop + } + DocumentMsg::SetPan(pan) => { + doc.pan = pan; + DocumentOp::Nop + } + DocumentMsg::SetWindowParameters{ window_size, inner_rect } => { + doc.window_size = window_size; + doc.inner_rect = inner_rect; + DocumentOp::Nop + } + DocumentMsg::SetDisplayList { + epoch, + pipeline_id, + background, + viewport_size, + content_size, + list_descriptor, + preserve_frame_state, + resources, + } => { + profile_scope!("SetDisplayList"); + + self.resource_cache.update_resources(resources, &mut profile_counters.resources); + + let mut data; + while { + data = self.payload_rx.recv_payload().unwrap(); + data.epoch != epoch || data.pipeline_id != pipeline_id + }{ + self.payload_tx.send_payload(data).unwrap() + } + + if let Some(ref mut r) = self.recorder { + r.write_payload(frame_counter, &data.to_data()); + } + + let built_display_list = BuiltDisplayList::from_data( + data.display_list_data, + list_descriptor + ); + + if !preserve_frame_state { + doc.frame.discard_frame_state_for_pipeline(pipeline_id); + } + + let display_list_len = built_display_list.data().len(); + let (builder_start_time, builder_finish_time, send_start_time) = built_display_list.times(); + let display_list_received_time = precise_time_ns(); + + { + self.webgl.flush(); + let _timer = profile_counters.total_time.timer(); + doc.scene.set_display_list( + pipeline_id, + epoch, + built_display_list, + background, + viewport_size, + content_size + ); + doc.build_scene(&mut self.resource_cache, self.hidpi_factor); + } + + if let Some(ref mut ros) = doc.render_on_scroll { + *ros = false; //wait for `GenerateFrame` + } + + // Note: this isn't quite right as auxiliary values will be + // pulled out somewhere in the prim_store, but aux values are + // really simple and cheap to access, so it's not a big deal. + let display_list_consumed_time = precise_time_ns(); + + profile_counters.ipc.set(builder_start_time, + builder_finish_time, + send_start_time, + display_list_received_time, + display_list_consumed_time, + display_list_len); + + DocumentOp::Built + } + DocumentMsg::SetRootPipeline(pipeline_id) => { + profile_scope!("SetRootPipeline"); + + doc.scene.set_root_pipeline_id(pipeline_id); + if doc.scene.display_lists.get(&pipeline_id).is_some() { + self.webgl.flush(); + let _timer = profile_counters.total_time.timer(); + doc.build_scene(&mut self.resource_cache, self.hidpi_factor); + DocumentOp::Built + } else { + DocumentOp::Nop + } + } + DocumentMsg::Scroll(delta, cursor, move_phase) => { + profile_scope!("Scroll"); + let _timer = profile_counters.total_time.timer(); + + if doc.frame.scroll(delta, cursor, move_phase) && doc.render_on_scroll == Some(true) { + let frame = doc.render(&mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor); + DocumentOp::Scrolled(frame) + } else { + DocumentOp::ScrolledNop + } + } + DocumentMsg::ScrollNodeWithId(origin, id, clamp) => { + profile_scope!("ScrollNodeWithScrollId"); + let _timer = profile_counters.total_time.timer(); + + if doc.frame.scroll_node(origin, id, clamp) && doc.render_on_scroll == Some(true) { + let frame = doc.render(&mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor); + DocumentOp::Scrolled(frame) + } else { + DocumentOp::ScrolledNop + } + } + DocumentMsg::TickScrollingBounce => { + profile_scope!("TickScrollingBounce"); + let _timer = profile_counters.total_time.timer(); + + doc.frame.tick_scrolling_bounce_animations(); + if doc.render_on_scroll == Some(true) { + let frame = doc.render(&mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor); + DocumentOp::Scrolled(frame) + } else { + DocumentOp::ScrolledNop + } + } + DocumentMsg::GetScrollNodeState(tx) => { + profile_scope!("GetScrollNodeState"); + tx.send(doc.frame.get_scroll_node_state()).unwrap(); + DocumentOp::Nop + } + DocumentMsg::GenerateFrame(property_bindings) => { + profile_scope!("GenerateFrame"); + let _timer = profile_counters.total_time.timer(); + + // Ideally, when there are property bindings present, + // we won't need to rebuild the entire frame here. + // However, to avoid conflicts with the ongoing work to + // refactor how scroll roots + transforms work, this + // just rebuilds the frame if there are animated property + // bindings present for now. + // TODO(gw): Once the scrolling / reference frame changes + // are completed, optimize the internals of + // animated properties to not require a full + // rebuild of the frame! + if let Some(property_bindings) = property_bindings { + self.webgl.flush(); + doc.scene.properties.set_properties(property_bindings); + doc.build_scene(&mut self.resource_cache, self.hidpi_factor); + } + + if let Some(ref mut ros) = doc.render_on_scroll { + *ros = true; + } + + if doc.scene.root_pipeline_id.is_some() { + let frame = doc.render(&mut self.resource_cache, + &mut self.gpu_cache, + &mut profile_counters.resources, + self.hidpi_factor); + DocumentOp::Rendered(frame) + } else { + DocumentOp::ScrolledNop + } } - None => self.notify_compositor_of_new_scroll_frame(false), } } @@ -144,337 +440,151 @@ impl RenderBackend { let mut frame_counter: u32 = 0; loop { - let msg = self.api_rx.recv(); profile_scope!("handle_msg"); - match msg { + + let msg = match self.api_rx.recv() { Ok(msg) => { if let Some(ref mut r) = self.recorder { r.write_msg(frame_counter, &msg); } - match msg { - ApiMsg::AddRawFont(id, bytes, index) => { - profile_counters.resources.font_templates.inc(bytes.len()); - self.resource_cache - .add_font_template(id, FontTemplate::Raw(Arc::new(bytes), index)); - } - ApiMsg::AddNativeFont(id, native_font_handle) => { - self.resource_cache - .add_font_template(id, FontTemplate::Native(native_font_handle)); - } - ApiMsg::DeleteFont(id) => { - self.resource_cache.delete_font_template(id); - } - ApiMsg::GetGlyphDimensions(font, glyph_keys, tx) => { - let mut glyph_dimensions = Vec::with_capacity(glyph_keys.len()); - for glyph_key in &glyph_keys { - let glyph_dim = self.resource_cache.get_glyph_dimensions(&font, glyph_key); - glyph_dimensions.push(glyph_dim); - }; - tx.send(glyph_dimensions).unwrap(); - } - ApiMsg::GetGlyphIndices(font_key, text, tx) => { - let mut glyph_indices = Vec::new(); - for ch in text.chars() { - let index = self.resource_cache.get_glyph_index(font_key, ch); - glyph_indices.push(index); - }; - tx.send(glyph_indices).unwrap(); - } - ApiMsg::AddImage(id, descriptor, data, tiling) => { - if let ImageData::Raw(ref bytes) = data { - profile_counters.resources.image_templates.inc(bytes.len()); - } - self.resource_cache.add_image_template(id, descriptor, data, tiling); - } - ApiMsg::UpdateImage(id, descriptor, bytes, dirty_rect) => { - self.resource_cache.update_image_template(id, descriptor, bytes, dirty_rect); - } - ApiMsg::DeleteImage(id) => { - self.resource_cache.delete_image_template(id); - } - ApiMsg::SetPageZoom(factor) => { - self.page_zoom_factor = factor.get(); - } - ApiMsg::SetPinchZoom(factor) => { - self.pinch_zoom_factor = factor.get(); - } - ApiMsg::SetPan(pan) => { - self.pan = pan; - } - ApiMsg::SetWindowParameters(window_size, inner_rect) => { - self.window_size = window_size; - self.inner_rect = inner_rect; - } - ApiMsg::CloneApi(sender) => { - let result = self.next_namespace_id; + msg + } + Err(..) => { + let notifier = self.notifier.lock(); + notifier.unwrap() + .as_mut() + .unwrap() + .shut_down(); + break; + } + }; - let IdNamespace(id_namespace) = self.next_namespace_id; - self.next_namespace_id = IdNamespace(id_namespace + 1); - - sender.send(result).unwrap(); + match msg { + ApiMsg::UpdateResources(updates) => { + self.resource_cache.update_resources(updates, &mut profile_counters.resources); + } + ApiMsg::GetGlyphDimensions(font, glyph_keys, tx) => { + let mut glyph_dimensions = Vec::with_capacity(glyph_keys.len()); + for glyph_key in &glyph_keys { + let glyph_dim = self.resource_cache.get_glyph_dimensions(&font, glyph_key); + glyph_dimensions.push(glyph_dim); + }; + tx.send(glyph_dimensions).unwrap(); + } + ApiMsg::GetGlyphIndices(font_key, text, tx) => { + let mut glyph_indices = Vec::new(); + for ch in text.chars() { + let index = self.resource_cache.get_glyph_index(font_key, ch); + glyph_indices.push(index); + }; + tx.send(glyph_indices).unwrap(); + } + ApiMsg::CloneApi(sender) => { + let namespace = self.next_namespace_id; + self.next_namespace_id = IdNamespace(namespace.0 + 1); + sender.send(namespace).unwrap(); + } + ApiMsg::AddDocument(document_id, initial_size) => { + let document = Document::new(self.frame_config.clone(), + initial_size, + self.enable_render_on_scroll); + self.documents.insert(document_id, document); + } + ApiMsg::UpdateDocument(document_id, doc_msg) => { + match self.process_document(document_id, doc_msg, frame_counter, &mut profile_counters) { + DocumentOp::Nop => {} + DocumentOp::Built => {} + DocumentOp::ScrolledNop => { + self.notify_compositor_of_new_scroll_frame(false); } - ApiMsg::SetDisplayList(background_color, - epoch, - pipeline_id, - viewport_size, - content_size, - display_list_descriptor, - preserve_frame_state) => { - profile_scope!("SetDisplayList"); - let mut leftover_data = vec![]; - let mut data; - loop { - data = self.payload_rx.recv_payload().unwrap(); - { - if data.epoch == epoch && - data.pipeline_id == pipeline_id { - break - } - } - leftover_data.push(data) - } - for leftover_data in leftover_data { - self.payload_tx.send_payload(leftover_data).unwrap() - } - if let Some(ref mut r) = self.recorder { - r.write_payload(frame_counter, &data.to_data()); - } - - let built_display_list = - BuiltDisplayList::from_data(data.display_list_data, - display_list_descriptor); - - if !preserve_frame_state { - self.discard_frame_state_for_pipeline(pipeline_id); - } - - let display_list_len = built_display_list.data().len(); - let (builder_start_time, builder_finish_time, send_start_time) = built_display_list.times(); - - let display_list_received_time = precise_time_ns(); - - profile_counters.total_time.profile(|| { - self.scene.set_display_list(pipeline_id, - epoch, - built_display_list, - background_color, - viewport_size, - content_size); - self.build_scene(); - }); - - self.render_on_scroll = false; //wait for `GenerateFrame` - - // Note: this isn't quite right as auxiliary values will be - // pulled out somewhere in the prim_store, but aux values are - // really simple and cheap to access, so it's not a big deal. - let display_list_consumed_time = precise_time_ns(); - - profile_counters.ipc.set(builder_start_time, - builder_finish_time, - send_start_time, - display_list_received_time, - display_list_consumed_time, - display_list_len); + DocumentOp::Scrolled(frame) => { + self.publish_frame(document_id, frame, &mut profile_counters); + self.notify_compositor_of_new_scroll_frame(true); } - ApiMsg::SetRootPipeline(pipeline_id) => { - profile_scope!("SetRootPipeline"); - self.scene.set_root_pipeline_id(pipeline_id); - - if self.scene.display_lists.get(&pipeline_id).is_none() { - continue; - } - - profile_counters.total_time.profile(|| { - self.build_scene(); - }) - } - ApiMsg::Scroll(delta, cursor, move_phase) => { - profile_scope!("Scroll"); - let frame = { - let counters = &mut profile_counters.resources.texture_cache; - let gpu_cache_counters = &mut profile_counters.resources.gpu_cache; - profile_counters.total_time.profile(|| { - if self.frame.scroll(delta, cursor, move_phase) && self.render_on_scroll { - Some(self.render(counters, gpu_cache_counters)) - } else { - None - } - }) - }; - - self.scroll_frame(frame, &mut profile_counters); - } - ApiMsg::ScrollNodeWithId(origin, id, clamp) => { - profile_scope!("ScrollNodeWithScrollId"); - let frame = { - let counters = &mut profile_counters.resources.texture_cache; - let gpu_cache_counters = &mut profile_counters.resources.gpu_cache; - profile_counters.total_time.profile(|| { - if self.frame.scroll_node(origin, id, clamp) && self.render_on_scroll { - Some(self.render(counters, gpu_cache_counters)) - } else { - None - } - }) - }; - - self.scroll_frame(frame, &mut profile_counters); - } - ApiMsg::TickScrollingBounce => { - profile_scope!("TickScrollingBounce"); - let frame = { - let counters = &mut profile_counters.resources.texture_cache; - let gpu_cache_counters = &mut profile_counters.resources.gpu_cache; - profile_counters.total_time.profile(|| { - self.frame.tick_scrolling_bounce_animations(); - if self.render_on_scroll { - Some(self.render(counters, gpu_cache_counters)) - } else { - None - } - }) - }; - - self.scroll_frame(frame, &mut profile_counters); - } - ApiMsg::TranslatePointToLayerSpace(..) => { - panic!("unused api - remove from webrender_api"); - } - ApiMsg::GetScrollNodeState(tx) => { - profile_scope!("GetScrollNodeState"); - tx.send(self.frame.get_scroll_node_state()).unwrap() - } - ApiMsg::RequestWebGLContext(size, attributes, tx) => { - if let Some(ref wrapper) = self.webrender_context_handle { - let dispatcher: Option> = if cfg!(target_os = "windows") { - Some(Box::new(WebRenderGLDispatcher { - dispatcher: Arc::clone(&self.main_thread_dispatcher) - })) - } else { - None - }; - - let result = wrapper.new_context(size, attributes, dispatcher); - // Creating a new GLContext may make the current bound context_id dirty. - // Clear it to ensure that make_current() is called in subsequent commands. - self.current_bound_webgl_context_id = None; - - match result { - Ok(ctx) => { - let id = WebGLContextId(self.next_webgl_id); - self.next_webgl_id += 1; - - let (real_size, texture_id, limits) = ctx.get_info(); - - self.webgl_contexts.insert(id, ctx); - - self.resource_cache - .add_webgl_texture(id, SourceTexture::WebGL(texture_id), - real_size); - - tx.send(Ok((id, limits))).unwrap(); - }, - Err(msg) => { - tx.send(Err(msg.to_owned())).unwrap(); - } - } - } else { - tx.send(Err("Not implemented yet".to_owned())).unwrap(); - } - } - ApiMsg::ResizeWebGLContext(context_id, size) => { - let ctx = self.webgl_contexts.get_mut(&context_id).unwrap(); - if Some(context_id) != self.current_bound_webgl_context_id { - ctx.make_current(); - self.current_bound_webgl_context_id = Some(context_id); - } - match ctx.resize(&size) { - Ok(_) => { - // Update webgl texture size. Texture id may change too. - let (real_size, texture_id, _) = ctx.get_info(); - self.resource_cache - .update_webgl_texture(context_id, SourceTexture::WebGL(texture_id), - real_size); - }, - Err(msg) => { - error!("Error resizing WebGLContext: {}", msg); - } - } - } - ApiMsg::WebGLCommand(context_id, command) => { - // TODO: Buffer the commands and only apply them here if they need to - // be synchronous. - let ctx = &self.webgl_contexts[&context_id]; - if Some(context_id) != self.current_bound_webgl_context_id { - ctx.make_current(); - self.current_bound_webgl_context_id = Some(context_id); - } - ctx.apply_command(command); - }, - - ApiMsg::VRCompositorCommand(context_id, command) => { - if Some(context_id) != self.current_bound_webgl_context_id { - self.webgl_contexts[&context_id].make_current(); - self.current_bound_webgl_context_id = Some(context_id); - } - self.handle_vr_compositor_command(context_id, command); - } - ApiMsg::GenerateFrame(property_bindings) => { - profile_scope!("GenerateFrame"); - - // Ideally, when there are property bindings present, - // we won't need to rebuild the entire frame here. - // However, to avoid conflicts with the ongoing work to - // refactor how scroll roots + transforms work, this - // just rebuilds the frame if there are animated property - // bindings present for now. - // TODO(gw): Once the scrolling / reference frame changes - // are completed, optimize the internals of - // animated properties to not require a full - // rebuild of the frame! - if let Some(property_bindings) = property_bindings { - self.scene.properties.set_properties(property_bindings); - profile_counters.total_time.profile(|| { - self.build_scene(); - }); - } - - self.render_on_scroll = self.enable_render_on_scroll; - - let frame = { - let counters = &mut profile_counters.resources.texture_cache; - let gpu_cache_counters = &mut profile_counters.resources.gpu_cache; - profile_counters.total_time.profile(|| { - self.render(counters, gpu_cache_counters) - }) - }; - if self.scene.root_pipeline_id.is_some() { - self.publish_frame_and_notify_compositor(frame, &mut profile_counters); - frame_counter += 1; - } - } - ApiMsg::ExternalEvent(evt) => { - let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .external_event(evt); - } - ApiMsg::ClearNamespace(namespace) => { - self.resource_cache.clear_namespace(namespace); - } - ApiMsg::ShutDown => { - let notifier = self.notifier.lock(); - notifier.unwrap() - .as_mut() - .unwrap() - .shut_down(); - break; + DocumentOp::Rendered(frame) => { + frame_counter += 1; + self.publish_frame_and_notify_compositor(document_id, frame, &mut profile_counters); } } } - Err(..) => { + ApiMsg::DeleteDocument(document_id) => { + self.documents.remove(&document_id); + } + ApiMsg::RequestWebGLContext(size, attributes, tx) => { + if let Some(ref wrapper) = self.webrender_context_handle { + let dispatcher: Option> = if cfg!(target_os = "windows") { + Some(Box::new(WebRenderGLDispatcher { + dispatcher: Arc::clone(&self.main_thread_dispatcher) + })) + } else { + None + }; + + let result = wrapper.new_context(size, attributes, dispatcher); + + match result { + Ok(ctx) => { + let (real_size, texture_id, limits) = ctx.get_info(); + let id = self.webgl.register(ctx); + + self.resource_cache + .add_webgl_texture(id, SourceTexture::WebGL(texture_id), + real_size); + + tx.send(Ok((id, limits))).unwrap(); + }, + Err(msg) => { + tx.send(Err(msg.to_owned())).unwrap(); + } + } + } else { + tx.send(Err("Not implemented yet".to_owned())).unwrap(); + } + } + ApiMsg::ResizeWebGLContext(context_id, size) => { + let ctx = self.webgl.activate(context_id); + match ctx.resize(&size) { + Ok(_) => { + // Update webgl texture size. Texture id may change too. + let (real_size, texture_id, _) = ctx.get_info(); + self.resource_cache + .update_webgl_texture(context_id, SourceTexture::WebGL(texture_id), + real_size); + }, + Err(msg) => { + error!("Error resizing WebGLContext: {}", msg); + } + } + } + ApiMsg::WebGLCommand(context_id, command) => { + // TODO: Buffer the commands and only apply them here if they need to + // be synchronous. + let ctx = self.webgl.activate(context_id); + ctx.apply_command(command); + }, + + ApiMsg::VRCompositorCommand(context_id, command) => { + self.webgl.activate(context_id); + self.handle_vr_compositor_command(context_id, command); + } + ApiMsg::ExternalEvent(evt) => { + let notifier = self.notifier.lock(); + notifier.unwrap() + .as_mut() + .unwrap() + .external_event(evt); + } + ApiMsg::ClearNamespace(namespace_id) => { + self.resource_cache.clear_namespace(namespace_id); + let document_ids = self.documents.keys() + .filter(|did| did.0 == namespace_id) + .cloned() + .collect::>(); + for document in document_ids { + self.documents.remove(&document); + } + } + ApiMsg::ShutDown => { let notifier = self.notifier.lock(); notifier.unwrap() .as_mut() @@ -486,72 +596,21 @@ impl RenderBackend { } } - fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) { - self.frame.discard_frame_state_for_pipeline(pipeline_id); - } - - fn accumulated_scale_factor(&self) -> f32 { - self.hidpi_factor * self.page_zoom_factor * self.pinch_zoom_factor - } - - fn build_scene(&mut self) { - // Flatten the stacking context hierarchy - if let Some(id) = self.current_bound_webgl_context_id { - self.webgl_contexts[&id].unbind(); - self.current_bound_webgl_context_id = None; - } - - // When running in OSMesa mode with texture sharing, - // a flush is required on any GL contexts to ensure - // that read-back from the shared texture returns - // valid data! This should be fine to have run on all - // implementations - a single flush for each webgl - // context at the start of a render frame should - // incur minimal cost. - for (_, webgl_context) in &self.webgl_contexts { - webgl_context.make_current(); - webgl_context.apply_command(WebGLCommand::Flush); - webgl_context.unbind(); - } - - let accumulated_scale_factor = self.accumulated_scale_factor(); - self.frame.create(&self.scene, - &mut self.resource_cache, - self.window_size, - self.inner_rect, - accumulated_scale_factor); - } - - fn render(&mut self, - texture_cache_profile: &mut TextureCacheProfileCounters, - gpu_cache_profile: &mut GpuCacheProfileCounters) - -> RendererFrame { - let accumulated_scale_factor = self.accumulated_scale_factor(); - let pan = LayerPoint::new(self.pan.x as f32 / accumulated_scale_factor, - self.pan.y as f32 / accumulated_scale_factor); - let frame = self.frame.build(&mut self.resource_cache, - &mut self.gpu_cache, - &self.scene.display_lists, - accumulated_scale_factor, - pan, - texture_cache_profile, - gpu_cache_profile); - frame - } - fn publish_frame(&mut self, + document_id: DocumentId, frame: RendererFrame, profile_counters: &mut BackendProfileCounters) { let pending_update = self.resource_cache.pending_updates(); - let msg = ResultMsg::NewFrame(frame, pending_update, profile_counters.clone()); + let msg = ResultMsg::NewFrame(document_id, frame, pending_update, profile_counters.clone()); self.result_tx.send(msg).unwrap(); profile_counters.reset(); } fn publish_frame_and_notify_compositor(&mut self, + document_id: DocumentId, frame: RendererFrame, profile_counters: &mut BackendProfileCounters) { - self.publish_frame(frame, profile_counters); + self.publish_frame(document_id, frame, profile_counters); // TODO(gw): This is kindof bogus to have to lock the notifier // each time it's used. This is due to some nastiness diff --git a/gfx/webrender/src/render_task.rs b/gfx/webrender/src/render_task.rs index 8753b78a2a2e..c6c4f8a028be 100644 --- a/gfx/webrender/src/render_task.rs +++ b/gfx/webrender/src/render_task.rs @@ -183,7 +183,7 @@ impl RenderTask { raw_clips: &[ClipWorkItem], extra_clip: Option) -> Option { - /// Filter out all the clip instances that don't contribute to the result + // Filter out all the clip instances that don't contribute to the result let mut inner_rect = Some(task_rect); let clips: Vec<_> = raw_clips.iter() .chain(extra_clip.iter()) diff --git a/gfx/webrender/src/renderer.rs b/gfx/webrender/src/renderer.rs index f5b7adc825e4..91359239d4c9 100644 --- a/gfx/webrender/src/renderer.rs +++ b/gfx/webrender/src/renderer.rs @@ -11,16 +11,15 @@ use debug_colors; use debug_render::DebugRenderer; -use device::{DepthFunction, Device, FrameId, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler, PBOId}; +use device::{DepthFunction, Device, FrameId, Program, TextureId, VertexDescriptor, GpuMarker, GpuProfiler, PBOId}; use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError}; -use device::get_gl_format_bgra; -use euclid::Transform3D; -use fnv::FnvHasher; +use device::{get_gl_format_bgra, VertexAttribute, VertexAttributeKind}; +use euclid::{Transform3D, rect}; use frame_builder::FrameBuilderConfig; use gleam::gl; use gpu_cache::{GpuBlockData, GpuCacheUpdate, GpuCacheUpdateList}; -use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp}; -use internal_types::{TextureUpdateList, PackedVertex, RenderTargetMode}; +use internal_types::{FastHashMap, CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp}; +use internal_types::{TextureUpdateList, RenderTargetMode}; use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture}; use internal_types::{BatchTextures, TextureSampler}; use profiler::{Profiler, BackendProfileCounters}; @@ -30,9 +29,8 @@ use render_backend::RenderBackend; use render_task::RenderTaskData; use std; use std::cmp; -use std::collections::{HashMap, VecDeque}; +use std::collections::VecDeque; use std::f32; -use std::hash::BuildHasherDefault; use std::marker::PhantomData; use std::mem; use std::path::PathBuf; @@ -49,8 +47,8 @@ use time::precise_time_ns; use thread_profiler::{register_thread_with_profiler, write_profile}; use util::TransformedRectKind; use webgl_types::GLContextHandleWrapper; -use api::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher}; -use api::{ExternalImageId, ExternalImageType, ImageData, ImageFormat, RenderApiSender}; +use api::{ColorF, Epoch, PipelineId, RenderApiSender, RenderNotifier, RenderDispatcher}; +use api::{ExternalImageId, ExternalImageType, ImageData, ImageFormat}; use api::{DeviceIntRect, DeviceUintRect, DeviceIntPoint, DeviceIntSize, DeviceUintSize}; use api::{BlobImageRenderer, channel, FontRenderMode}; use api::VRCompositorHandler; @@ -84,6 +82,62 @@ const GPU_TAG_PRIM_BORDER_EDGE: GpuProfileTag = GpuProfileTag { label: "BorderEd const GPU_TAG_PRIM_CACHE_IMAGE: GpuProfileTag = GpuProfileTag { label: "CacheImage", color: debug_colors::SILVER }; const GPU_TAG_BLUR: GpuProfileTag = GpuProfileTag { label: "Blur", color: debug_colors::VIOLET }; +bitflags! { + #[derive(Default)] + pub struct DebugFlags: u32 { + const PROFILER_DBG = 1 << 0; + const RENDER_TARGET_DBG = 1 << 1; + const TEXTURE_CACHE_DBG = 1 << 2; + } +} + +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct PackedVertex { + pub pos: [f32; 2], +} + +const DESC_PRIM_INSTANCES: VertexDescriptor = VertexDescriptor { + vertex_attributes: &[ + VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + ], + instance_attributes: &[ + VertexAttribute { name: "aData0", count: 4, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aData1", count: 4, kind: VertexAttributeKind::I32 }, + ] +}; + +const DESC_BLUR: VertexDescriptor = VertexDescriptor { + vertex_attributes: &[ + VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + ], + instance_attributes: &[ + VertexAttribute { name: "aBlurRenderTaskIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aBlurSourceTaskIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aBlurDirection", count: 1, kind: VertexAttributeKind::I32 }, + ] +}; + +const DESC_CLIP: VertexDescriptor = VertexDescriptor { + vertex_attributes: &[ + VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 }, + ], + instance_attributes: &[ + VertexAttribute { name: "aClipRenderTaskIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aClipLayerIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aClipDataIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aClipSegmentIndex", count: 1, kind: VertexAttributeKind::I32 }, + VertexAttribute { name: "aClipResourceAddress", count: 1, kind: VertexAttributeKind::I32 }, + ] +}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum VertexFormat { + PrimitiveInstances, + Blur, + Clip, +} + #[derive(Clone, Debug, PartialEq)] pub enum GraphicsApi { OpenGL, @@ -102,6 +156,7 @@ pub enum ImageBufferKind { TextureRect = 1, TextureExternal = 2, } + pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 3] = [ ImageBufferKind::Texture2D, ImageBufferKind::TextureRect, @@ -434,7 +489,7 @@ enum ShaderKind { } struct LazilyCompiledShader { - id: Option, + program: Option, name: &'static str, kind: ShaderKind, features: Vec<&'static str>, @@ -447,7 +502,7 @@ impl LazilyCompiledShader { device: &mut Device, precache: bool) -> Result { let mut shader = LazilyCompiledShader { - id: None, + program: None, name, kind, features: features.to_vec(), @@ -460,15 +515,22 @@ impl LazilyCompiledShader { Ok(shader) } - fn get(&mut self, device: &mut Device) -> Result { - if self.id.is_none() { - let id = try!{ + fn bind(&mut self, device: &mut Device, projection: &Transform3D) { + let program = self.get(device) + .expect("Unable to get shader!"); + device.bind_program(program); + device.set_uniforms(program, projection); + } + + fn get(&mut self, device: &mut Device) -> Result<&Program, ShaderError> { + if self.program.is_none() { + let program = try!{ match self.kind { ShaderKind::Primitive => { create_prim_shader(self.name, device, &self.features, - VertexFormat::Triangles) + VertexFormat::PrimitiveInstances) } ShaderKind::Cache(format) => { create_prim_shader(self.name, @@ -481,10 +543,16 @@ impl LazilyCompiledShader { } } }; - self.id = Some(id); + self.program = Some(program); } - Ok(self.id.unwrap()) + Ok(self.program.as_ref().unwrap()) + } + + fn deinit(&mut self, device: &mut Device) { + if let &mut Some(ref mut program) = &mut self.program { + device.delete_program(program); + } } } @@ -506,17 +574,6 @@ impl FileWatcherHandler for FileWatcher { } } -fn _get_ubo_max_len(max_ubo_size: usize) -> usize { - let item_size = mem::size_of::(); - let max_items = max_ubo_size / item_size; - - // TODO(gw): Clamping to 1024 since some shader compilers - // seem to go very slow when you have high - // constants for array lengths. Investigate - // whether this clamping actually hurts performance! - cmp::min(max_items, 1024) -} - impl PrimitiveShader { fn new(name: &'static str, device: &mut Device, @@ -547,20 +604,26 @@ impl PrimitiveShader { }) } - fn get(&mut self, - device: &mut Device, - transform_kind: TransformedRectKind) -> Result { + fn bind(&mut self, + device: &mut Device, + transform_kind: TransformedRectKind, + projection: &Transform3D) { match transform_kind { - TransformedRectKind::AxisAligned => self.simple.get(device), - TransformedRectKind::Complex => self.transform.get(device), + TransformedRectKind::AxisAligned => self.simple.bind(device, projection), + TransformedRectKind::Complex => self.transform.bind(device, projection), } } + + fn deinit(&mut self, device: &mut Device) { + self.simple.deinit(device); + self.transform.deinit(device); + } } fn create_prim_shader(name: &'static str, device: &mut Device, features: &[&'static str], - vertex_format: VertexFormat) -> Result { + vertex_format: VertexFormat) -> Result { let mut prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n", MAX_VERTEX_TEXTURE_WIDTH); @@ -571,10 +634,20 @@ fn create_prim_shader(name: &'static str, debug!("PrimShader {}", name); let includes = &["prim_shared"]; - device.create_program_with_prefix(name, includes, Some(prefix), vertex_format) + + let vertex_descriptor = match vertex_format { + VertexFormat::PrimitiveInstances => DESC_PRIM_INSTANCES, + VertexFormat::Blur => DESC_BLUR, + VertexFormat::Clip => DESC_CLIP, + }; + + device.create_program_with_prefix(name, + includes, + Some(prefix), + &vertex_descriptor) } -fn create_clip_shader(name: &'static str, device: &mut Device) -> Result { +fn create_clip_shader(name: &'static str, device: &mut Device) -> Result { let prefix = format!("#define WR_MAX_VERTEX_TEXTURE_WIDTH {}\n #define WR_FEATURE_TRANSFORM", MAX_VERTEX_TEXTURE_WIDTH); @@ -582,7 +655,7 @@ fn create_clip_shader(name: &'static str, device: &mut Device) -> Result>>>, - enable_profiler: bool, + max_texture_size: u32, + max_recorded_profiles: usize, clear_framebuffer: bool, clear_color: ColorF, enable_clear_scissor: bool, debug: DebugRenderer, - render_target_debug: bool, + debug_flags: DebugFlags, enable_batcher: bool, backend_profile_counters: BackendProfileCounters, profile_counters: RendererProfileCounters, @@ -693,7 +767,7 @@ pub struct Renderer { gpu_cache_texture: CacheTexture, - pipeline_epoch_map: HashMap>, + pipeline_epoch_map: FastHashMap, /// Used to dispatch functions to the main thread's event loop. /// Required to allow GLContext sharing in some implementations like WGL. main_thread_dispatcher: Arc>>>, @@ -720,7 +794,7 @@ pub struct Renderer { external_image_handler: Option>, /// Map of external image IDs to native textures. - external_images: HashMap<(ExternalImageId, u8), TextureId, BuildHasherDefault>, + external_images: FastHashMap<(ExternalImageId, u8), TextureId>, // Optional trait object that handles WebVR commands. // Some WebVR commands such as SubmitFrame must be synced with the WebGL render thread. @@ -760,14 +834,11 @@ impl Renderer { /// device_pixel_ratio: 1.0, /// resource_override_path: None, /// enable_aa: false, - /// enable_profiler: false, /// }; /// let (renderer, sender) = Renderer::new(opts); /// ``` /// [rendereroptions]: struct.RendererOptions.html - pub fn new(gl: Rc, - mut options: RendererOptions, - initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> { + pub fn new(gl: Rc, mut options: RendererOptions) -> Result<(Renderer, RenderApiSender), InitError> { let (api_tx, api_rx) = try!{ channel::msg_channel() }; let (payload_tx, payload_rx) = try!{ channel::payload_channel() }; let (result_tx, result_rx) = channel(); @@ -789,7 +860,7 @@ impl Renderer { device.begin_frame(1.0); let cs_box_shadow = try!{ - LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::Triangles), + LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::PrimitiveInstances), "cs_box_shadow", &[], &mut device, @@ -797,7 +868,7 @@ impl Renderer { }; let cs_text_run = try!{ - LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::Triangles), + LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::PrimitiveInstances), "cs_text_run", &[], &mut device, @@ -805,7 +876,7 @@ impl Renderer { }; let cs_line = try!{ - LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::Triangles), + LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::PrimitiveInstances), "ps_line", &["CACHE"], &mut device, @@ -1113,13 +1184,13 @@ impl Renderer { }, ]; - let prim_vao_id = device.create_vao(VertexFormat::Triangles, mem::size_of::() as i32); + let prim_vao_id = device.create_vao(&DESC_PRIM_INSTANCES, mem::size_of::() as i32); device.bind_vao(prim_vao_id); device.update_vao_indices(prim_vao_id, &quad_indices, VertexUsageHint::Static); device.update_vao_main_vertices(prim_vao_id, &quad_vertices, VertexUsageHint::Static); - let blur_vao_id = device.create_vao_with_new_instances(VertexFormat::Blur, mem::size_of::() as i32, prim_vao_id); - let clip_vao_id = device.create_vao_with_new_instances(VertexFormat::Clip, mem::size_of::() as i32, prim_vao_id); + let blur_vao_id = device.create_vao_with_new_instances(&DESC_BLUR, mem::size_of::() as i32, prim_vao_id); + let clip_vao_id = device.create_vao_with_new_instances(&DESC_CLIP, mem::size_of::() as i32, prim_vao_id); device.end_frame(); @@ -1151,7 +1222,7 @@ impl Renderer { }; let device_pixel_ratio = options.device_pixel_ratio; - let render_target_debug = options.render_target_debug; + let debug_flags = options.debug_flags; let payload_tx_for_backend = payload_tx.clone(); let recorder = options.recorder; let worker_config = ThreadPoolConfig::new() @@ -1178,7 +1249,6 @@ impl Renderer { backend_main_thread_dispatcher, blob_image_renderer, backend_vr_compositor, - initial_window_size, enable_render_on_scroll); backend.run(backend_profile_counters); })}; @@ -1221,12 +1291,12 @@ impl Renderer { ps_line, notifier, debug: debug_renderer, - render_target_debug, + debug_flags, enable_batcher: options.enable_batcher, backend_profile_counters: BackendProfileCounters::new(), profile_counters: RendererProfileCounters::new(), profiler: Profiler::new(), - enable_profiler: options.enable_profiler, + max_texture_size: max_texture_size, max_recorded_profiles: options.max_recorded_profiles, clear_framebuffer: options.clear_framebuffer, clear_color: options.clear_color, @@ -1240,13 +1310,13 @@ impl Renderer { clip_vao_id, gdt_index: 0, gpu_data_textures, - pipeline_epoch_map: HashMap::default(), + pipeline_epoch_map: FastHashMap::default(), main_thread_dispatcher, cache_texture_id_map: Vec::new(), dummy_cache_texture_id, dither_matrix_texture_id, external_image_handler: None, - external_images: HashMap::default(), + external_images: FastHashMap::default(), vr_compositor_handler: vr_compositor, cpu_profiles: VecDeque::new(), gpu_profiles: VecDeque::new(), @@ -1257,6 +1327,10 @@ impl Renderer { Ok((renderer, sender)) } + pub fn get_max_texture_size(&self) -> u32 { + self.max_texture_size + } + pub fn get_graphics_api_info(&self) -> GraphicsApiInfo { GraphicsApiInfo { kind: GraphicsApi::OpenGL, @@ -1302,8 +1376,8 @@ impl Renderer { /// Returns a HashMap containing the pipeline ids that have been received by the renderer and /// their respective epochs since the last time the method was called. - pub fn flush_rendered_epochs(&mut self) -> HashMap> { - mem::replace(&mut self.pipeline_epoch_map, HashMap::default()) + pub fn flush_rendered_epochs(&mut self) -> FastHashMap { + mem::replace(&mut self.pipeline_epoch_map, FastHashMap::default()) } /// Processes the result queue. @@ -1315,7 +1389,8 @@ impl Renderer { // Pull any pending results and return the most recent. while let Ok(msg) = self.result_rx.try_recv() { match msg { - ResultMsg::NewFrame(mut frame, texture_update_list, profile_counters) => { + ResultMsg::NewFrame(_document_id, mut frame, texture_update_list, profile_counters) => { + //TODO: associate `document_id` with target window self.pending_texture_updates.push(texture_update_list); if let Some(ref mut frame) = frame.frame { // TODO(gw): This whole message / Frame / RendererFrame stuff @@ -1376,8 +1451,8 @@ impl Renderer { /// Renders the current frame. /// - /// A Frame is supplied by calling [`set_display_list()`][newframe]. - /// [newframe]: ../../webrender_api/struct.RenderApi.html#method.set_display_list + /// A Frame is supplied by calling [`generate_frame()`][genframe]. + /// [genframe]: ../../webrender_api/struct.DocumentApi.html#method.generate_frame pub fn render(&mut self, framebuffer_size: DeviceUintSize) { profile_scope!("render"); @@ -1442,7 +1517,7 @@ impl Renderer { self.cpu_profiles.push_back(cpu_profile); } - if self.enable_profiler { + if self.debug_flags.contains(PROFILER_DBG) { self.profiler.draw_profile(&mut self.device, &frame.profile_counters, &self.backend_profile_counters, @@ -1619,11 +1694,8 @@ impl Renderer { fn draw_instanced_batch(&mut self, data: &[T], vao: VAOId, - shader: ProgramId, - textures: &BatchTextures, - projection: &Transform3D) { + textures: &BatchTextures) { self.device.bind_vao(vao); - self.device.bind_program(shader, projection); for i in 0..textures.colors.len() { let texture_id = self.resolve_source_texture(&textures.colors[i]); @@ -1667,80 +1739,92 @@ impl Renderer { BlendMode::None => false, }); - let (marker, shader) = match batch.key.kind { + let marker = match batch.key.kind { AlphaBatchKind::Composite => { - let shader = self.ps_composite.get(&mut self.device); - (GPU_TAG_PRIM_COMPOSITE, shader) + self.ps_composite.bind(&mut self.device, projection); + GPU_TAG_PRIM_COMPOSITE } AlphaBatchKind::HardwareComposite => { - let shader = self.ps_hw_composite.get(&mut self.device); - (GPU_TAG_PRIM_HW_COMPOSITE, shader) + self.ps_hw_composite.bind(&mut self.device, projection); + GPU_TAG_PRIM_HW_COMPOSITE } AlphaBatchKind::SplitComposite => { - let shader = self.ps_split_composite.get(&mut self.device); - (GPU_TAG_PRIM_SPLIT_COMPOSITE, shader) + self.ps_split_composite.bind(&mut self.device, projection); + GPU_TAG_PRIM_SPLIT_COMPOSITE } AlphaBatchKind::Blend => { - let shader = self.ps_blend.get(&mut self.device); - (GPU_TAG_PRIM_BLEND, shader) + self.ps_blend.bind(&mut self.device, projection); + GPU_TAG_PRIM_BLEND } AlphaBatchKind::Rectangle => { - let shader = if needs_clipping { - self.ps_rectangle_clip.get(&mut self.device, transform_kind) + if needs_clipping { + self.ps_rectangle_clip.bind(&mut self.device, transform_kind, projection); } else { - self.ps_rectangle.get(&mut self.device, transform_kind) - }; - (GPU_TAG_PRIM_RECT, shader) + self.ps_rectangle.bind(&mut self.device, transform_kind, projection); + } + GPU_TAG_PRIM_RECT } AlphaBatchKind::Line => { - let shader = self.ps_line.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_LINE, shader) + self.ps_line.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_LINE } AlphaBatchKind::TextRun => { - let shader = match batch.key.blend_mode { - BlendMode::Subpixel(..) => self.ps_text_run_subpixel.get(&mut self.device, transform_kind), - BlendMode::Alpha | BlendMode::PremultipliedAlpha | BlendMode::None => self.ps_text_run.get(&mut self.device, transform_kind), + match batch.key.blend_mode { + BlendMode::Subpixel(..) => { + self.ps_text_run_subpixel.bind(&mut self.device, transform_kind, projection); + } + BlendMode::Alpha | + BlendMode::PremultipliedAlpha | + BlendMode::None => { + self.ps_text_run.bind(&mut self.device, transform_kind, projection); + } }; - (GPU_TAG_PRIM_TEXT_RUN, shader) + GPU_TAG_PRIM_TEXT_RUN } AlphaBatchKind::Image(image_buffer_kind) => { - let shader = self.ps_image[image_buffer_kind as usize].as_mut().unwrap().get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_IMAGE, shader) + self.ps_image[image_buffer_kind as usize] + .as_mut() + .expect("Unsupported image shader kind") + .bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_IMAGE } AlphaBatchKind::YuvImage(image_buffer_kind, format, color_space) => { let shader_index = Renderer::get_yuv_shader_index(image_buffer_kind, format, color_space); - let shader = self.ps_yuv_image[shader_index].as_mut().unwrap().get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_YUV_IMAGE, shader) + self.ps_yuv_image[shader_index] + .as_mut() + .expect("Unsupported YUV shader kind") + .bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_YUV_IMAGE } AlphaBatchKind::BorderCorner => { - let shader = self.ps_border_corner.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_BORDER_CORNER, shader) + self.ps_border_corner.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_BORDER_CORNER } AlphaBatchKind::BorderEdge => { - let shader = self.ps_border_edge.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_BORDER_EDGE, shader) + self.ps_border_edge.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_BORDER_EDGE } AlphaBatchKind::AlignedGradient => { - let shader = self.ps_gradient.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_GRADIENT, shader) + self.ps_gradient.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_GRADIENT } AlphaBatchKind::AngleGradient => { - let shader = self.ps_angle_gradient.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_ANGLE_GRADIENT, shader) + self.ps_angle_gradient.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_ANGLE_GRADIENT } AlphaBatchKind::RadialGradient => { - let shader = self.ps_radial_gradient.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_RADIAL_GRADIENT, shader) + self.ps_radial_gradient.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_RADIAL_GRADIENT } AlphaBatchKind::BoxShadow => { - let shader = self.ps_box_shadow.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_BOX_SHADOW, shader) + self.ps_box_shadow.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_BOX_SHADOW } AlphaBatchKind::CacheImage => { - let shader = self.ps_cache_image.get(&mut self.device, transform_kind); - (GPU_TAG_PRIM_CACHE_IMAGE, shader) + self.ps_cache_image.bind(&mut self.device, transform_kind, projection); + GPU_TAG_PRIM_CACHE_IMAGE } }; @@ -1803,14 +1887,11 @@ impl Renderer { self.device.bind_draw_target(render_target, Some(target_dimensions)); } - let shader = shader.unwrap(); let _gm = self.gpu_profile.add_marker(marker); let vao = self.prim_vao_id; self.draw_instanced_batch(&batch.instances, vao, - shader, - &batch.key.textures, - projection); + &batch.key.textures); } fn draw_color_target(&mut self, @@ -1858,22 +1939,18 @@ impl Renderer { let vao = self.blur_vao_id; self.device.set_blend(false); - let shader = self.cs_blur.get(&mut self.device).unwrap(); + self.cs_blur.bind(&mut self.device, projection); if !target.vertical_blurs.is_empty() { self.draw_instanced_batch(&target.vertical_blurs, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } if !target.horizontal_blurs.is_empty() { self.draw_instanced_batch(&target.horizontal_blurs, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } } @@ -1882,12 +1959,10 @@ impl Renderer { self.device.set_blend(false); let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_BOX_SHADOW); let vao = self.prim_vao_id; - let shader = self.cs_box_shadow.get(&mut self.device).unwrap(); + self.cs_box_shadow.bind(&mut self.device, projection); self.draw_instanced_batch(&target.box_shadow_cache_prims, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } // Draw any textrun caches for this target. For now, this @@ -1902,13 +1977,10 @@ impl Renderer { let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_TEXT_RUN); let vao = self.prim_vao_id; - let shader = self.cs_text_run.get(&mut self.device).unwrap(); - + self.cs_text_run.bind(&mut self.device, projection); self.draw_instanced_batch(&target.text_run_cache_prims, vao, - shader, - &target.text_run_textures, - &projection); + &target.text_run_textures); } if !target.line_cache_prims.is_empty() { // TODO(gw): Technically, we don't need blend for solid @@ -1918,13 +1990,10 @@ impl Renderer { let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_LINE); let vao = self.prim_vao_id; - let shader = self.cs_line.get(&mut self.device).unwrap(); - + self.cs_line.bind(&mut self.device, projection); self.draw_instanced_batch(&target.line_cache_prims, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } if !target.alpha_batcher.is_empty() { @@ -2022,12 +2091,10 @@ impl Renderer { if !target.clip_batcher.border_clears.is_empty() { let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip borders [clear]"); self.device.set_blend(false); - let shader = self.cs_clip_border.get(&mut self.device).unwrap(); + self.cs_clip_border.bind(&mut self.device, projection); self.draw_instanced_batch(&target.clip_batcher.border_clears, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } // Draw any dots or dashes for border corners. @@ -2039,12 +2106,10 @@ impl Renderer { // a max blend mode here is fine. self.device.set_blend(true); self.device.set_blend_mode_max(); - let shader = self.cs_clip_border.get(&mut self.device).unwrap(); + self.cs_clip_border.bind(&mut self.device, projection); self.draw_instanced_batch(&target.clip_batcher.borders, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } // switch to multiplicative blending @@ -2054,12 +2119,10 @@ impl Renderer { // draw rounded cornered rectangles if !target.clip_batcher.rectangles.is_empty() { let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip rectangles"); - let shader = self.cs_clip_rectangle.get(&mut self.device).unwrap(); + self.cs_clip_rectangle.bind(&mut self.device, projection); self.draw_instanced_batch(&target.clip_batcher.rectangles, vao, - shader, - &BatchTextures::no_texture(), - &projection); + &BatchTextures::no_texture()); } // draw image masks for (mask_texture_id, items) in target.clip_batcher.images.iter() { @@ -2071,12 +2134,10 @@ impl Renderer { SourceTexture::Invalid, ] }; - let shader = self.cs_clip_image.get(&mut self.device).unwrap(); + self.cs_clip_image.bind(&mut self.device, projection); self.draw_instanced_batch(items, vao, - shader, - &textures, - &projection); + &textures); } } } @@ -2290,6 +2351,7 @@ impl Renderer { self.color_render_targets.reverse(); self.alpha_render_targets.reverse(); self.draw_render_target_debug(framebuffer_size); + self.draw_texture_cache_debug(framebuffer_size); } self.unlock_external_images(); @@ -2299,12 +2361,12 @@ impl Renderer { &mut self.debug } - pub fn get_profiler_enabled(&mut self) -> bool { - self.enable_profiler + pub fn get_debug_flags(&self) -> DebugFlags { + self.debug_flags } - pub fn set_profiler_enabled(&mut self, enabled: bool) { - self.enable_profiler = enabled; + pub fn set_debug_flags(&mut self, flags: DebugFlags) { + self.debug_flags = flags; } pub fn save_cpu_profile(&self, filename: &str) { @@ -2313,39 +2375,67 @@ impl Renderer { fn draw_render_target_debug(&mut self, framebuffer_size: &DeviceUintSize) { - if self.render_target_debug { - // TODO(gw): Make the layout of the render targets a bit more sophisticated. - // Right now, it just draws them in one row at the bottom of the screen, - // with a fixed size. - let rt_debug_x0 = 16; - let rt_debug_y0 = 16; - let rt_debug_spacing = 16; - let rt_debug_size = 512; - let mut current_target = 0; + if !self.debug_flags.contains(RENDER_TARGET_DBG) { + return; + } - for texture_id in self.color_render_targets.iter().chain(self.alpha_render_targets.iter()) { - let layer_count = self.device.get_render_target_layer_count(*texture_id); - for layer_index in 0..layer_count { - let x0 = rt_debug_x0 + (rt_debug_spacing + rt_debug_size) * current_target; - let y0 = rt_debug_y0; + let mut spacing = 16; + let mut size = 512; + let fb_width = framebuffer_size.width as i32; + let num_textures = self.color_render_targets.iter().chain(self.alpha_render_targets.iter()).count() as i32; - // If we have more targets than fit on one row in screen, just early exit. - if x0 > framebuffer_size.width as i32 { - return; - } + if num_textures * (size + spacing) > fb_width { + let factor = fb_width as f32 / (num_textures * (size + spacing)) as f32; + size = (size as f32 * factor) as i32; + spacing = (spacing as f32 * factor) as i32; + } - let dest_rect = DeviceIntRect::new(DeviceIntPoint::new(x0, y0), - DeviceIntSize::new(rt_debug_size, rt_debug_size)); - self.device.blit_render_target(Some((*texture_id, layer_index as i32)), - None, - dest_rect); + for (i, texture_id) in self.color_render_targets.iter().chain(self.alpha_render_targets.iter()).enumerate() { + let layer_count = self.device.get_render_target_layer_count(*texture_id); + for layer_index in 0..layer_count { + let x = fb_width - (spacing + size) * (i as i32 + 1); + let y = spacing; - current_target += 1; - } + let dest_rect = rect(x, y, size, size); + self.device.blit_render_target( + Some((*texture_id, layer_index as i32)), + None, + dest_rect + ); } } } + fn draw_texture_cache_debug(&mut self, framebuffer_size: &DeviceUintSize) { + if !self.debug_flags.contains(TEXTURE_CACHE_DBG) { + return; + } + + let mut spacing = 16; + let mut size = 512; + let fb_width = framebuffer_size.width as i32; + let num_textures = self.cache_texture_id_map.len() as i32; + + if num_textures * (size + spacing) > fb_width { + let factor = fb_width as f32 / (num_textures * (size + spacing)) as f32; + size = (size as f32 * factor) as i32; + spacing = (spacing as f32 * factor) as i32; + } + + for (i, texture_id) in self.cache_texture_id_map.iter().enumerate() { + let x = fb_width - (spacing + size) * (i as i32 + 1); + let y = spacing + if self.debug_flags.contains(RENDER_TARGET_DBG) { 528 } else { 0 }; + + // If we have more targets than fit on one row in screen, just early exit. + if x > fb_width { + return; + } + + let dest_rect = rect(x, y, size, size); + self.device.blit_render_target(Some((*texture_id, 0)), None, dest_rect); + } + } + pub fn read_pixels_rgba8(&self, rect: DeviceUintRect) -> Vec { let mut pixels = vec![0u8; (4 * rect.size.width * rect.size.height) as usize]; self.read_pixels_into(rect, ReadPixelsFormat::Rgba8, &mut pixels); @@ -2376,6 +2466,40 @@ impl Renderer { //Note: this is a fake frame, only needed because texture deletion is require to happen inside a frame self.device.begin_frame(1.0); self.device.deinit_texture(self.dummy_cache_texture_id); + self.debug.deinit(&mut self.device); + self.cs_box_shadow.deinit(&mut self.device); + self.cs_text_run.deinit(&mut self.device); + self.cs_line.deinit(&mut self.device); + self.cs_blur.deinit(&mut self.device); + self.cs_clip_rectangle.deinit(&mut self.device); + self.cs_clip_image.deinit(&mut self.device); + self.cs_clip_border.deinit(&mut self.device); + self.ps_rectangle.deinit(&mut self.device); + self.ps_rectangle_clip.deinit(&mut self.device); + self.ps_text_run.deinit(&mut self.device); + self.ps_text_run_subpixel.deinit(&mut self.device); + for shader in &mut self.ps_image { + if let &mut Some(ref mut shader) = shader { + shader.deinit(&mut self.device); + } + } + for shader in &mut self.ps_yuv_image { + if let &mut Some(ref mut shader) = shader { + shader.deinit(&mut self.device); + } + } + self.ps_border_corner.deinit(&mut self.device); + self.ps_border_edge.deinit(&mut self.device); + self.ps_gradient.deinit(&mut self.device); + self.ps_angle_gradient.deinit(&mut self.device); + self.ps_radial_gradient.deinit(&mut self.device); + self.ps_box_shadow.deinit(&mut self.device); + self.ps_cache_image.deinit(&mut self.device); + self.ps_line.deinit(&mut self.device); + self.ps_blend.deinit(&mut self.device); + self.ps_hw_composite.deinit(&mut self.device); + self.ps_split_composite.deinit(&mut self.device); + self.ps_composite.deinit(&mut self.device); self.device.end_frame(); } } @@ -2423,7 +2547,6 @@ pub struct RendererOptions { pub resource_override_path: Option, pub enable_aa: bool, pub enable_dithering: bool, - pub enable_profiler: bool, pub max_recorded_profiles: usize, pub debug: bool, pub enable_scrollbars: bool, @@ -2434,13 +2557,13 @@ pub struct RendererOptions { pub clear_color: ColorF, pub enable_clear_scissor: bool, pub enable_batcher: bool, - pub render_target_debug: bool, pub max_texture_size: Option, pub cache_expiry_frames: u32, pub workers: Option>, pub blob_image_renderer: Option>, pub recorder: Option>, pub enable_render_on_scroll: bool, + pub debug_flags: DebugFlags, } impl Default for RendererOptions { @@ -2450,7 +2573,7 @@ impl Default for RendererOptions { resource_override_path: None, enable_aa: true, enable_dithering: true, - enable_profiler: false, + debug_flags: DebugFlags::empty(), max_recorded_profiles: 0, debug: false, enable_scrollbars: false, @@ -2461,7 +2584,6 @@ impl Default for RendererOptions { clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0), enable_clear_scissor: true, enable_batcher: true, - render_target_debug: false, max_texture_size: None, cache_expiry_frames: 600, // roughly, 10 seconds workers: None, diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs index 439e3ad1a69b..beefd856fcee 100644 --- a/gfx/webrender/src/resource_cache.rs +++ b/gfx/webrender/src/resource_cache.rs @@ -3,28 +3,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use device::TextureFilter; -use fnv::FnvHasher; use frame::FrameId; +use glyph_cache::GlyphCache; use gpu_cache::{GpuCache, GpuCacheHandle}; -use internal_types::{SourceTexture, TextureUpdateList}; -use profiler::TextureCacheProfileCounters; -use std::collections::{HashMap, HashSet}; +use internal_types::{FastHashMap, FastHashSet, SourceTexture, TextureUpdateList}; +use profiler::{ResourceProfileCounters, TextureCacheProfileCounters}; +use std::cmp; use std::collections::hash_map::Entry::{self, Occupied, Vacant}; use std::fmt::Debug; -use std::hash::BuildHasherDefault; use std::hash::Hash; use std::mem; use std::sync::Arc; use texture_cache::{TextureCache, TextureCacheItemId}; -use api::{Epoch, FontInstanceKey, FontKey, FontTemplate, GlyphKey, ImageKey, ImageRendering}; -use api::{ImageData, GlyphDimensions, WebGLContextId, IdNamespace}; -use api::{DevicePoint, DeviceIntSize, DeviceUintRect, ImageDescriptor}; -use api::{GlyphInstance, SubpixelPoint, TileOffset, TileSize}; -use api::{BlobImageRenderer, BlobImageDescriptor, BlobImageError, BlobImageRequest, BlobImageData}; -use api::BlobImageResources; -use api::{ExternalImageData, ExternalImageType, LayoutPoint}; +use api::{BlobImageRenderer, BlobImageDescriptor, BlobImageError, BlobImageRequest}; +use api::{BlobImageResources, BlobImageData, ResourceUpdates, ResourceUpdate, AddFont}; +use api::{DevicePoint, DeviceIntSize, DeviceUintRect, DeviceUintSize}; +use api::{Epoch, FontInstanceKey, FontKey, FontTemplate}; +use api::{GlyphDimensions, GlyphKey, IdNamespace}; +use api::{ImageData, ImageDescriptor, ImageKey, ImageRendering}; +use api::{TileOffset, TileSize}; +use api::{ExternalImageData, ExternalImageType, WebGLContextId}; use rayon::ThreadPool; -use glyph_rasterizer::{GlyphRasterizer, GlyphCache, GlyphRequest}; +use glyph_rasterizer::{GlyphRasterizer, GlyphRequest}; const DEFAULT_TILE_SIZE: TileSize = 512; @@ -65,14 +65,22 @@ struct ImageResource { dirty_rect: Option } +#[derive(Debug)] +pub struct ImageTiling { + pub image_size: DeviceUintSize, + pub tile_size: TileSize, +} + +pub type TiledImageMap = FastHashMap; + struct ImageTemplates { - images: HashMap>, + images: FastHashMap, } impl ImageTemplates { fn new() -> Self { ImageTemplates { - images: HashMap::with_hasher(Default::default()) + images: FastHashMap::default() } } @@ -96,65 +104,79 @@ impl ImageTemplates { struct CachedImageInfo { texture_cache_id: TextureCacheItemId, epoch: Epoch, + last_access: FrameId, } pub struct ResourceClassCache { - resources: HashMap>, - last_access_times: HashMap>, + resources: FastHashMap, } impl ResourceClassCache where K: Clone + Hash + Eq + Debug, V: Resource { pub fn new() -> ResourceClassCache { ResourceClassCache { - resources: HashMap::default(), - last_access_times: HashMap::default(), + resources: FastHashMap::default(), } } fn get(&self, key: &K, frame: FrameId) -> &V { + let resource = self.resources + .get(key) + .expect("Didn't find a cached resource with that ID!"); + // This assert catches cases in which we accidentally request a resource that we forgot to // mark as needed this frame. - debug_assert_eq!(frame, *self.last_access_times - .get(key) - .expect("Didn't find the access time for a cached resource \ - with that ID!")); - self.resources.get(key).expect("Didn't find a cached resource with that ID!") + debug_assert_eq!(frame, resource.get_last_access_time()); + + resource } - pub fn insert(&mut self, key: K, value: V, frame: FrameId) { - self.last_access_times.insert(key.clone(), frame); + pub fn insert(&mut self, key: K, value: V) { self.resources.insert(key, value); } pub fn entry(&mut self, key: K, frame: FrameId) -> Entry { - self.last_access_times.insert(key.clone(), frame); - self.resources.entry(key) + let mut entry = self.resources.entry(key); + match entry { + Occupied(ref mut entry) => { + entry.get_mut().set_last_access_time(frame); + } + Vacant(..) => {} + } + entry } - pub fn mark_as_needed(&mut self, key: &K, frame: FrameId) { - self.last_access_times.insert((*key).clone(), frame); + pub fn is_empty(&self) -> bool { + self.resources.is_empty() } - fn expire_old_resources(&mut self, texture_cache: &mut TextureCache, frame_id: FrameId) { - //TODO: use retain when available - let resources_to_destroy = self.last_access_times.iter() - .filter_map(|(key, this_frame_id)| { - if *this_frame_id < frame_id { - Some(key.clone()) - } else { - None - } - }).collect::>(); + pub fn update(&mut self, + texture_cache: &mut TextureCache, + gpu_cache: &mut GpuCache, + current_frame_id: FrameId, + expiry_frame_id: FrameId) { + let mut resources_to_destroy = Vec::new(); + + for (key, resource) in &self.resources { + let last_access = resource.get_last_access_time(); + if last_access < expiry_frame_id { + resources_to_destroy.push(key.clone()); + } else if last_access == current_frame_id { + resource.add_to_gpu_cache(texture_cache, gpu_cache); + } + } for key in resources_to_destroy { let resource = self.resources .remove(&key) .expect("Resource was in `last_access_times` but not in `resources`!"); - self.last_access_times.remove(&key); - if let Some(texture_cache_item_id) = resource.texture_cache_item_id() { - texture_cache.free(texture_cache_item_id) - } + resource.free(texture_cache); + } + } + + pub fn clear(&mut self, texture_cache: &mut TextureCache) { + for (_, resource) in self.resources.drain() { + resource.free(texture_cache); } } @@ -167,9 +189,7 @@ impl ResourceClassCache where K: Clone + Hash + Eq + Debug, V: Resourc .collect::>(); for key in resources_to_destroy { let resource = self.resources.remove(&key).unwrap(); - if let Some(texture_cache_item_id) = resource.texture_cache_item_id() { - texture_cache.free(texture_cache_item_id) - } + resource.free(texture_cache); } } } @@ -197,7 +217,7 @@ pub struct WebGLTexture { } struct Resources { - font_templates: HashMap>, + font_templates: FastHashMap, image_templates: ImageTemplates, } @@ -215,7 +235,7 @@ pub struct ResourceCache { cached_images: ResourceClassCache, // TODO(pcwalton): Figure out the lifecycle of these. - webgl_textures: HashMap>, + webgl_textures: FastHashMap, resources: Resources, state: State, @@ -224,41 +244,40 @@ pub struct ResourceCache { texture_cache: TextureCache, // TODO(gw): We should expire (parts of) this cache semi-regularly! - cached_glyph_dimensions: HashMap, BuildHasherDefault>, - pending_image_requests: Vec, + cached_glyph_dimensions: FastHashMap>, glyph_rasterizer: GlyphRasterizer, - blob_image_renderer: Option>, - blob_image_requests: HashSet, + // The set of images that aren't present or valid in the texture cache, + // and need to be rasterized and/or uploaded this frame. This includes + // both blobs and regular images. + pending_image_requests: FastHashSet, - requested_glyphs: HashSet>, - requested_images: HashSet>, + blob_image_renderer: Option>, + + cache_expiry_frames: u32, } impl ResourceCache { pub fn new(texture_cache: TextureCache, workers: Arc, - blob_image_renderer: Option>) -> ResourceCache { + blob_image_renderer: Option>, + cache_expiry_frames: u32) -> ResourceCache { ResourceCache { - cached_glyphs: ResourceClassCache::new(), + cached_glyphs: GlyphCache::new(), cached_images: ResourceClassCache::new(), - webgl_textures: HashMap::default(), + webgl_textures: FastHashMap::default(), resources: Resources { - font_templates: HashMap::default(), + font_templates: FastHashMap::default(), image_templates: ImageTemplates::new(), }, - cached_glyph_dimensions: HashMap::default(), + cached_glyph_dimensions: FastHashMap::default(), texture_cache, state: State::Idle, current_frame_id: FrameId(0), - pending_image_requests: Vec::new(), + pending_image_requests: FastHashSet::default(), glyph_rasterizer: GlyphRasterizer::new(workers), - blob_image_renderer, - blob_image_requests: HashSet::new(), - - requested_glyphs: HashSet::default(), - requested_images: HashSet::default(), + cache_expiry_frames, } } @@ -279,6 +298,47 @@ impl ResourceCache { } } + pub fn update_resources( + &mut self, + updates: ResourceUpdates, + profile_counters: &mut ResourceProfileCounters + ) { + // TODO, there is potential for optimization here, by processing updates in + // bulk rather than one by one (for example by sorting allocations by size or + // in a way that reduces fragmentation in the atlas). + + for update in updates.updates { + match update { + ResourceUpdate::AddImage(img) => { + if let ImageData::Raw(ref bytes) = img.data { + profile_counters.image_templates.inc(bytes.len()); + } + self.add_image_template(img.key, img.descriptor, img.data, img.tiling); + } + ResourceUpdate::UpdateImage(img) => { + self.update_image_template(img.key, img.descriptor, img.data, img.dirty_rect); + } + ResourceUpdate::DeleteImage(img) => { + self.delete_image_template(img); + } + ResourceUpdate::AddFont(font) => { + match font { + AddFont::Raw(id, bytes, index) => { + profile_counters.font_templates.inc(bytes.len()); + self.add_font_template(id, FontTemplate::Raw(Arc::new(bytes), index)); + } + AddFont::Native(id, native_font_handle) => { + self.add_font_template(id, FontTemplate::Native(native_font_handle)); + } + } + } + ResourceUpdate::DeleteFont(font) => { + self.delete_font_template(font); + } + } + } + } + pub fn add_font_template(&mut self, font_key: FontKey, template: FontTemplate) { // Push the new font to the font renderer, and also store // it locally for glyph metric requests. @@ -366,6 +426,8 @@ impl ResourceCache { pub fn delete_image_template(&mut self, image_key: ImageKey) { let value = self.resources.image_templates.remove(image_key); + self.cached_images.clear_keys(&mut self.texture_cache, |request| request.key == image_key); + match value { Some(image) => { if image.data.is_blob() { @@ -406,28 +468,31 @@ impl ResourceCache { }; let template = self.resources.image_templates.get(key).unwrap(); - if template.data.uses_texture_cache() { - self.cached_images.mark_as_needed(&request, self.current_frame_id); + + // Images that don't use the texture cache can early out. + if !template.data.uses_texture_cache() { + return; } - if template.data.is_blob() { - if let Some(ref mut renderer) = self.blob_image_renderer { - let (same_epoch, texture_cache_id) = match self.cached_images.resources - .get(&request) { - Some(entry) => { - (entry.epoch == template.epoch, Some(entry.texture_cache_id)) - } - None => { - (false, None) - } - }; - // Ensure that blobs are added to the list of requested items - // foe the GPU cache, even if the cached blob image is up to date. - if let Some(texture_cache_id) = texture_cache_id { - self.requested_images.insert(texture_cache_id); + // If this image exists in the texture cache, *and* the epoch + // in the cache matches that of the template, then it is + // valid to use as-is. + match self.cached_images.entry(request, self.current_frame_id) { + Occupied(entry) => { + let cached_image = entry.get(); + if cached_image.epoch == template.epoch { + return; } + } + Vacant(..) => {} + } - if !same_epoch && self.blob_image_requests.insert(request) { + // We can start a worker thread rasterizing right now, if: + // - The image is a blob. + // - The blob hasn't already been requested this frame. + if self.pending_image_requests.insert(request) { + if template.data.is_blob() { + if let Some(ref mut renderer) = self.blob_image_renderer { let (offset, w, h) = match template.tiling { Some(tile_size) => { let tile_offset = request.tile.unwrap(); @@ -457,22 +522,19 @@ impl ResourceCache { ); } } - } else { - self.pending_image_requests.push(request); } } pub fn request_glyphs(&mut self, font: FontInstanceKey, - glyph_instances: &[GlyphInstance]) { + glyph_keys: &[GlyphKey]) { debug_assert_eq!(self.state, State::AddResources); self.glyph_rasterizer.request_glyphs( &mut self.cached_glyphs, self.current_frame_id, font, - glyph_instances, - &mut self.requested_glyphs, + glyph_keys, ); } @@ -482,22 +544,16 @@ impl ResourceCache { pub fn get_glyphs(&self, font: FontInstanceKey, - glyph_instances: &[GlyphInstance], + glyph_keys: &[GlyphKey], mut f: F) -> SourceTexture where F: FnMut(usize, &GpuCacheHandle) { debug_assert_eq!(self.state, State::QueryResources); - let mut glyph_request = GlyphRequest::new( - font, - 0, - LayoutPoint::zero(), - ); let mut texture_id = None; - for (loop_index, glyph_instance) in glyph_instances.iter().enumerate() { - glyph_request.key.index = glyph_instance.index; - glyph_request.key.subpixel_point = SubpixelPoint::new(glyph_instance.point, - glyph_request.font.render_mode); - let image_id = self.cached_glyphs.get(&glyph_request, self.current_frame_id); - let cache_item = image_id.map(|image_id| self.texture_cache.get(image_id)); + let glyph_key_cache = self.cached_glyphs.get_glyph_key_cache_for_font(&font); + + for (loop_index, key) in glyph_keys.iter().enumerate() { + let glyph = glyph_key_cache.get(key, self.current_frame_id); + let cache_item = glyph.texture_cache_id.map(|image_id| self.texture_cache.get(image_id)); if let Some(cache_item) = cache_item { f(loop_index, &cache_item.uv_rect_handle); debug_assert!(texture_id == None || @@ -511,11 +567,8 @@ impl ResourceCache { pub fn get_glyph_dimensions(&mut self, font: &FontInstanceKey, - glyph_key: &GlyphKey) -> Option { - let key = GlyphRequest { - font: font.clone(), - key: glyph_key.clone(), - }; + key: &GlyphKey) -> Option { + let key = GlyphRequest::new(font, key); match self.cached_glyph_dimensions.entry(key.clone()) { Occupied(entry) => *entry.get(), @@ -574,6 +627,16 @@ impl ResourceCache { } } + pub fn get_tiled_image_map(&self) -> TiledImageMap { + self.resources.image_templates.images.iter().filter_map(|(&key, template)| + template.tiling.map(|tile_size| (key, ImageTiling { + image_size: DeviceUintSize::new(template.descriptor.width, + template.descriptor.height), + tile_size, + })) + ).collect() + } + pub fn get_webgl_texture(&self, context_id: &WebGLContextId) -> &WebGLTexture { &self.webgl_textures[context_id] } @@ -582,17 +645,10 @@ impl ResourceCache { self.webgl_textures[context_id].size } - pub fn expire_old_resources(&mut self, frame_id: FrameId) { - self.cached_images.expire_old_resources(&mut self.texture_cache, frame_id); - self.cached_glyphs.expire_old_resources(&mut self.texture_cache, frame_id); - } - pub fn begin_frame(&mut self, frame_id: FrameId) { debug_assert_eq!(self.state, State::Idle); self.state = State::AddResources; self.current_frame_id = frame_id; - debug_assert!(self.requested_glyphs.is_empty()); - debug_assert!(self.requested_images.is_empty()); } pub fn block_until_all_resources_added(&mut self, @@ -607,112 +663,105 @@ impl ResourceCache { self.current_frame_id, &mut self.cached_glyphs, &mut self.texture_cache, - &mut self.requested_glyphs, texture_cache_profile, ); - let mut image_requests = mem::replace(&mut self.pending_image_requests, Vec::new()); - for request in image_requests.drain(..) { - self.finalize_image_request(request, None, texture_cache_profile); - } + // Apply any updates of new / updated images (incl. blobs) to the texture cache. + self.update_texture_cache(texture_cache_profile); - let mut blob_image_requests = mem::replace(&mut self.blob_image_requests, HashSet::new()); - if self.blob_image_renderer.is_some() { - for request in blob_image_requests.drain() { - match self.blob_image_renderer.as_mut().unwrap().resolve(request.into()) { - Ok(image) => { - self.finalize_image_request(request, - Some(ImageData::new(image.data)), - texture_cache_profile); - } - // TODO(nical): I think that we should handle these somewhat gracefully, - // at least in the out-of-memory scenario. - Err(BlobImageError::Oom) => { - // This one should be recoverable-ish. - panic!("Failed to render a vector image (OOM)"); - } - Err(BlobImageError::InvalidKey) => { - panic!("Invalid vector image key"); - } - Err(BlobImageError::InvalidData) => { - // TODO(nical): If we run into this we should kill the content process. - panic!("Invalid vector image data"); - } - Err(BlobImageError::Other(msg)) => { - panic!("Vector image error {}", msg); - } - } - } - } - - for texture_cache_item_id in self.requested_images.drain() { - let item = self.texture_cache.get_mut(texture_cache_item_id); - if let Some(mut request) = gpu_cache.request(&mut item.uv_rect_handle) { - request.push(item.uv_rect); - } - } - - for texture_cache_item_id in self.requested_glyphs.drain() { - let item = self.texture_cache.get_mut(texture_cache_item_id); - if let Some(mut request) = gpu_cache.request(&mut item.uv_rect_handle) { - request.push(item.uv_rect); - request.push([item.user_data[0], item.user_data[1], 0.0, 0.0]); - } - } + // Expire any resources that haven't been used for `cache_expiry_frames`. + let num_frames_back = self.cache_expiry_frames; + let expiry_frame = FrameId(cmp::max(num_frames_back, self.current_frame_id.0) - num_frames_back); + self.cached_images.update(&mut self.texture_cache, + gpu_cache, + self.current_frame_id, + expiry_frame); + self.cached_glyphs.update(&mut self.texture_cache, + gpu_cache, + self.current_frame_id, + expiry_frame); } - fn update_texture_cache(&mut self, - request: &ImageRequest, - image_data: Option, - texture_cache_profile: &mut TextureCacheProfileCounters) { - let image_template = self.resources.image_templates.get_mut(request.key).unwrap(); - let image_data = image_data.unwrap_or_else(||{ - image_template.data.clone() - }); + fn update_texture_cache(&mut self, texture_cache_profile: &mut TextureCacheProfileCounters) { + for request in self.pending_image_requests.drain() { + let image_template = self.resources.image_templates.get_mut(request.key).unwrap(); + debug_assert!(image_template.data.uses_texture_cache()); - let filter = match request.rendering { - ImageRendering::Pixelated => TextureFilter::Nearest, - ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear, - }; - - let descriptor = if let Some(tile) = request.tile { - let tile_size = image_template.tiling.unwrap(); - let image_descriptor = &image_template.descriptor; - - let (actual_width, actual_height) = compute_tile_size(image_descriptor, tile_size, tile); - - // The tiled image could be stored on the CPU as one large image or be - // already broken up into tiles. This affects the way we compute the stride - // and offset. - let tiled_on_cpu = image_template.data.is_blob(); - - let (stride, offset) = if tiled_on_cpu { - (image_descriptor.stride, 0) - } else { - let bpp = image_descriptor.format.bytes_per_pixel().unwrap(); - let stride = image_descriptor.compute_stride(); - let offset = image_descriptor.offset + tile.y as u32 * tile_size as u32 * stride - + tile.x as u32 * tile_size as u32 * bpp; - (Some(stride), offset) + let image_data = match image_template.data { + ImageData::Raw(..) | ImageData::External(..) => { + // Safe to clone here since the Raw image data is an + // Arc, and the external image data is small. + image_template.data.clone() + } + ImageData::Blob(..) => { + // Extract the rasterized image from the blob renderer. + match self.blob_image_renderer.as_mut().unwrap().resolve(request.into()) { + Ok(image) => ImageData::new(image.data), + // TODO(nical): I think that we should handle these somewhat gracefully, + // at least in the out-of-memory scenario. + Err(BlobImageError::Oom) => { + // This one should be recoverable-ish. + panic!("Failed to render a vector image (OOM)"); + } + Err(BlobImageError::InvalidKey) => { + panic!("Invalid vector image key"); + } + Err(BlobImageError::InvalidData) => { + // TODO(nical): If we run into this we should kill the content process. + panic!("Invalid vector image data"); + } + Err(BlobImageError::Other(msg)) => { + panic!("Vector image error {}", msg); + } + } + } }; - ImageDescriptor { - width: actual_width, - height: actual_height, - stride, - offset, - format: image_descriptor.format, - is_opaque: image_descriptor.is_opaque, - } - } else { - image_template.descriptor.clone() - }; + let filter = match request.rendering { + ImageRendering::Pixelated => TextureFilter::Nearest, + ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear, + }; - let image_id = match self.cached_images.entry(*request, self.current_frame_id) { - Occupied(entry) => { - let image_id = entry.get().texture_cache_id; + let descriptor = if let Some(tile) = request.tile { + let tile_size = image_template.tiling.unwrap(); + let image_descriptor = &image_template.descriptor; - if entry.get().epoch != image_template.epoch { + let (actual_width, actual_height) = compute_tile_size(image_descriptor, tile_size, tile); + + // The tiled image could be stored on the CPU as one large image or be + // already broken up into tiles. This affects the way we compute the stride + // and offset. + let tiled_on_cpu = image_template.data.is_blob(); + + let (stride, offset) = if tiled_on_cpu { + (image_descriptor.stride, 0) + } else { + let bpp = image_descriptor.format.bytes_per_pixel().unwrap(); + let stride = image_descriptor.compute_stride(); + let offset = image_descriptor.offset + tile.y as u32 * tile_size as u32 * stride + + tile.x as u32 * tile_size as u32 * bpp; + (Some(stride), offset) + }; + + ImageDescriptor { + width: actual_width, + height: actual_height, + stride, + offset, + format: image_descriptor.format, + is_opaque: image_descriptor.is_opaque, + } + } else { + image_template.descriptor.clone() + }; + + match self.cached_images.entry(request, self.current_frame_id) { + Occupied(entry) => { + let image_id = entry.get().texture_cache_id; + + // We should only get to this code path if the image + // definitely needs to be updated. + debug_assert!(entry.get().epoch != image_template.epoch); self.texture_cache.update(image_id, descriptor, filter, @@ -720,62 +769,28 @@ impl ResourceCache { image_template.dirty_rect); // Update the cached epoch + debug_assert_eq!(self.current_frame_id, entry.get().last_access); *entry.into_mut() = CachedImageInfo { texture_cache_id: image_id, epoch: image_template.epoch, + last_access: self.current_frame_id, }; image_template.dirty_rect = None; } + Vacant(entry) => { + let image_id = self.texture_cache.insert(descriptor, + filter, + image_data, + [0.0; 2], + texture_cache_profile); - image_id - } - Vacant(entry) => { - let filter = match request.rendering { - ImageRendering::Pixelated => TextureFilter::Nearest, - ImageRendering::Auto | ImageRendering::CrispEdges => TextureFilter::Linear, - }; - - let image_id = self.texture_cache.insert(descriptor, - filter, - image_data, - [0.0; 2], - texture_cache_profile); - - entry.insert(CachedImageInfo { - texture_cache_id: image_id, - epoch: image_template.epoch, - }); - - image_id - } - }; - - self.requested_images.insert(image_id); - } - fn finalize_image_request(&mut self, - request: ImageRequest, - image_data: Option, - texture_cache_profile: &mut TextureCacheProfileCounters) { - match self.resources.image_templates.get(request.key).unwrap().data { - ImageData::External(ext_image) => { - match ext_image.image_type { - ExternalImageType::Texture2DHandle | - ExternalImageType::TextureRectHandle | - ExternalImageType::TextureExternalHandle => { - // external handle doesn't need to update the texture_cache. - } - ExternalImageType::ExternalBuffer => { - self.update_texture_cache(&request, - image_data, - texture_cache_profile); - } + entry.insert(CachedImageInfo { + texture_cache_id: image_id, + epoch: image_template.epoch, + last_access: self.current_frame_id, + }); } - } - ImageData::Raw(..) | ImageData::Blob(..) => { - self.update_texture_cache(&request, - image_data, - texture_cache_profile); - } + }; } } @@ -803,33 +818,39 @@ impl ResourceCache { } self.cached_images.clear_keys(&mut self.texture_cache, |request| request.key.0 == namespace); - self.cached_glyphs.clear_keys(&mut self.texture_cache, |request| request.font.font_key.0 == namespace); + self.cached_glyphs.clear_fonts(&mut self.texture_cache, |font| font.font_key.0 == namespace); } } pub trait Resource { - fn texture_cache_item_id(&self) -> Option; -} - -impl Resource for TextureCacheItemId { - fn texture_cache_item_id(&self) -> Option { - Some(*self) - } -} - -impl Resource for Option { - fn texture_cache_item_id(&self) -> Option { - *self - } + fn free(&self, texture_cache: &mut TextureCache); + fn get_last_access_time(&self) -> FrameId; + fn set_last_access_time(&mut self, frame_id: FrameId); + fn add_to_gpu_cache(&self, + texture_cache: &mut TextureCache, + gpu_cache: &mut GpuCache); } impl Resource for CachedImageInfo { - fn texture_cache_item_id(&self) -> Option { - Some(self.texture_cache_id) + fn free(&self, texture_cache: &mut TextureCache) { + texture_cache.free(self.texture_cache_id); + } + fn get_last_access_time(&self) -> FrameId { + self.last_access + } + fn set_last_access_time(&mut self, frame_id: FrameId) { + self.last_access = frame_id; + } + fn add_to_gpu_cache(&self, + texture_cache: &mut TextureCache, + gpu_cache: &mut GpuCache) { + let item = texture_cache.get_mut(self.texture_cache_id); + if let Some(mut request) = gpu_cache.request(&mut item.uv_rect_handle) { + request.push(item.uv_rect); + } } } - // Compute the width and height of a tile depending on its position in the image. pub fn compute_tile_size(descriptor: &ImageDescriptor, base_size: TileSize, diff --git a/gfx/webrender/src/scene.rs b/gfx/webrender/src/scene.rs index 485abcedabad..ea7a7f28a13c 100644 --- a/gfx/webrender/src/scene.rs +++ b/gfx/webrender/src/scene.rs @@ -2,25 +2,23 @@ * 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 fnv::FnvHasher; -use std::collections::HashMap; -use std::hash::BuildHasherDefault; use api::{BuiltDisplayList, ColorF, DynamicProperties, Epoch, LayerSize, LayoutSize}; use api::{LayoutTransform, PipelineId, PropertyBinding, PropertyBindingId}; +use internal_types::FastHashMap; /// Stores a map of the animated property bindings for the current display list. These /// can be used to animate the transform and/or opacity of a display list without /// re-submitting the display list itself. pub struct SceneProperties { - transform_properties: HashMap, - float_properties: HashMap, + transform_properties: FastHashMap, + float_properties: FastHashMap, } impl SceneProperties { pub fn new() -> SceneProperties { SceneProperties { - transform_properties: HashMap::default(), - float_properties: HashMap::default(), + transform_properties: FastHashMap::default(), + float_properties: FastHashMap::default(), } } @@ -91,8 +89,8 @@ pub struct ScenePipeline { /// A complete representation of the layout bundling visible pipelines together. pub struct Scene { pub root_pipeline_id: Option, - pub pipeline_map: HashMap>, - pub display_lists: HashMap>, + pub pipeline_map: FastHashMap, + pub display_lists: FastHashMap, pub properties: SceneProperties, } @@ -100,8 +98,8 @@ impl Scene { pub fn new() -> Scene { Scene { root_pipeline_id: None, - pipeline_map: HashMap::default(), - display_lists: HashMap::default(), + pipeline_map: FastHashMap::default(), + display_lists: FastHashMap::default(), properties: SceneProperties::new(), } } diff --git a/gfx/webrender/src/texture_cache.rs b/gfx/webrender/src/texture_cache.rs index 26d01beeb98d..7366d3de4290 100644 --- a/gfx/webrender/src/texture_cache.rs +++ b/gfx/webrender/src/texture_cache.rs @@ -3,16 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use device::TextureFilter; -use fnv::FnvHasher; use freelist::{FreeList, FreeListItem, FreeListItemId}; use gpu_cache::GpuCacheHandle; -use internal_types::{TextureUpdate, TextureUpdateOp, UvRect}; +use internal_types::{FastHashMap, TextureUpdate, TextureUpdateOp, UvRect}; use internal_types::{CacheTextureId, RenderTargetMode, TextureUpdateList}; use profiler::TextureCacheProfileCounters; use std::cmp; -use std::collections::HashMap; use std::collections::hash_map::Entry; -use std::hash::BuildHasherDefault; use std::mem; use std::slice::Iter; use time; @@ -575,7 +572,7 @@ impl CacheTextureIdList { pub struct TextureCache { cache_id_list: CacheTextureIdList, - free_texture_levels: HashMap, BuildHasherDefault>, + free_texture_levels: FastHashMap>, items: FreeList, arena: TextureCacheArena, pending_updates: TextureUpdateList, @@ -603,7 +600,7 @@ impl TextureCache { TextureCache { cache_id_list: CacheTextureIdList::new(), - free_texture_levels: HashMap::default(), + free_texture_levels: FastHashMap::default(), items: FreeList::new(), pending_updates: TextureUpdateList::new(), arena: TextureCacheArena::new(), @@ -688,9 +685,18 @@ impl TextureCache { ImageFormat::Invalid | ImageFormat::RGBAF32 => unreachable!(), }; + // TODO(gw): Handle this sensibly (support failing to render items that can't fit?) - assert!(requested_size.width <= self.max_texture_size); - assert!(requested_size.height <= self.max_texture_size); + assert!( + requested_size.width <= self.max_texture_size, + "Width {:?} > max texture size (format: {:?}).", + requested_size.width, format + ); + assert!( + requested_size.height <= self.max_texture_size, + "Height {:?} > max texture size (format: {:?}).", + requested_size.height, format + ); let mut page_id = None; //using ID here to please the borrow checker for (i, page) in page_list.iter_mut().enumerate() { @@ -816,8 +822,23 @@ impl TextureCache { } let op = match data { - ImageData::External(..) => { - panic!("Doesn't support Update() for external image."); + ImageData::External(ext_image) => { + match ext_image.image_type { + ExternalImageType::Texture2DHandle | + ExternalImageType::TextureRectHandle | + ExternalImageType::TextureExternalHandle => { + panic!("External texture handle should not go through texture_cache."); + } + ExternalImageType::ExternalBuffer => { + TextureUpdateOp::UpdateForExternalBuffer { + rect: existing_item.allocated_rect, + id: ext_image.id, + channel_index: ext_image.channel_index, + stride: descriptor.stride, + offset: descriptor.offset, + } + } + } } ImageData::Blob(..) => { panic!("The vector image should have been rasterized into a raw image."); diff --git a/gfx/webrender/src/tiling.rs b/gfx/webrender/src/tiling.rs index d54c531de1d5..e5104aaad969 100644 --- a/gfx/webrender/src/tiling.rs +++ b/gfx/webrender/src/tiling.rs @@ -4,10 +4,9 @@ use border::{BorderCornerInstance, BorderCornerSide}; use device::TextureId; -use fnv::FnvHasher; use gpu_cache::{GpuCache, GpuCacheHandle, GpuCacheUpdateList}; use internal_types::{BatchTextures, CacheTextureId}; -use internal_types::SourceTexture; +use internal_types::{FastHashMap, SourceTexture}; use mask_cache::MaskCacheInfo; use prim_store::{CLIP_DATA_GPU_BLOCKS, DeferredResolve, ImagePrimitiveKind, PrimitiveCacheKey}; use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; @@ -19,8 +18,6 @@ use renderer::BlendMode; use renderer::ImageBufferKind; use resource_cache::ResourceCache; use std::{f32, i32, mem, usize}; -use std::collections::HashMap; -use std::hash::BuildHasherDefault; use texture_cache::TexturePage; use util::{TransformedRect, TransformedRectKind}; use api::{BuiltDisplayList, ClipAndScrollInfo, ClipId, ColorF, DeviceIntPoint, ImageKey}; @@ -34,9 +31,7 @@ use api::{TileOffset, WorldToLayerTransform, YuvColorSpace, YuvFormat, LayerVect const OPAQUE_TASK_INDEX: RenderTaskIndex = RenderTaskIndex(i32::MAX as usize); -pub type DisplayListMap = HashMap>; +pub type DisplayListMap = FastHashMap; trait AlphaBatchHelpers { fn get_blend_mode(&self, @@ -110,14 +105,14 @@ struct DynamicTaskInfo { #[derive(Debug)] pub struct RenderTaskCollection { pub render_task_data: Vec, - dynamic_tasks: HashMap<(RenderTaskKey, RenderPassIndex), DynamicTaskInfo, BuildHasherDefault>, + dynamic_tasks: FastHashMap<(RenderTaskKey, RenderPassIndex), DynamicTaskInfo>, } impl RenderTaskCollection { pub fn new(static_render_task_count: usize) -> RenderTaskCollection { RenderTaskCollection { render_task_data: vec![RenderTaskData::empty(); static_render_task_count], - dynamic_tasks: HashMap::default(), + dynamic_tasks: FastHashMap::default(), } } @@ -493,15 +488,14 @@ impl AlphaRenderItem { font_size_dp, text_cpu.color, text_cpu.normal_render_mode, - text_cpu.glyph_options); + text_cpu.glyph_options, + text_cpu.subpx_dir); let texture_id = ctx.resource_cache.get_glyphs(font, - &text_cpu.glyph_instances, + &text_cpu.glyph_keys, |index, handle| { let uv_address = handle.as_int(gpu_cache); - instances.push(base_instance.build(index as i32, - text_cpu.normal_render_mode as i32, - uv_address)); + instances.push(base_instance.build(index as i32, uv_address, 0)); }); if texture_id != SourceTexture::Invalid { @@ -684,7 +678,7 @@ pub struct ClipBatcher { /// Rectangle draws fill up the rectangles with rounded corners. pub rectangles: Vec, /// Image draws apply the image masking. - pub images: HashMap>, + pub images: FastHashMap>, pub border_clears: Vec, pub borders: Vec, } @@ -693,7 +687,7 @@ impl ClipBatcher { fn new() -> ClipBatcher { ClipBatcher { rectangles: Vec::new(), - images: HashMap::new(), + images: FastHashMap::default(), border_clears: Vec::new(), borders: Vec::new(), } @@ -1012,7 +1006,6 @@ impl RenderTarget for ColorRenderTarget { task_id: render_tasks.get_task_index(&task.id, pass_index).0 as i32, src_task_id: render_tasks.get_task_index(&src_id, child_pass_index).0 as i32, blur_direction: BlurDirection::Vertical as i32, - padding: 0, }); } RenderTaskKind::HorizontalBlur(blur_radius, prim_index) => { @@ -1024,7 +1017,6 @@ impl RenderTarget for ColorRenderTarget { task_id: render_tasks.get_task_index(&task.id, pass_index).0 as i32, src_task_id: render_tasks.get_task_index(&src_id, child_pass_index).0 as i32, blur_direction: BlurDirection::Horizontal as i32, - padding: 0, }); } RenderTaskKind::CachePrimitive(prim_index) => { @@ -1070,10 +1062,11 @@ impl RenderTarget for ColorRenderTarget { font_size_dp, text.color, text.shadow_render_mode, - text.glyph_options); + text.glyph_options, + text.subpx_dir); let texture_id = ctx.resource_cache.get_glyphs(font, - &text.glyph_instances, + &text.glyph_keys, |index, handle| { let uv_address = handle.as_int(gpu_cache); instances.push(instance.build(index as i32, @@ -1376,7 +1369,6 @@ pub struct BlurCommand { task_id: i32, src_task_id: i32, blur_direction: i32, - padding: i32, } /// A clipping primitive drawn into the clipping mask. diff --git a/gfx/webrender_api/Cargo.toml b/gfx/webrender_api/Cargo.toml index 57bf48842a0b..d68a81393db5 100644 --- a/gfx/webrender_api/Cargo.toml +++ b/gfx/webrender_api/Cargo.toml @@ -15,6 +15,7 @@ app_units = "0.5" bincode = "0.8" byteorder = "1.0" euclid = "0.15" +fxhash = "0.2.1" gleam = "0.4.5" heapsize = ">= 0.3.6, < 0.5" ipc-channel = {version = "0.8", optional = true} diff --git a/gfx/webrender_api/src/api.rs b/gfx/webrender_api/src/api.rs index dbfbdf6ef034..2948bc990734 100644 --- a/gfx/webrender_api/src/api.rs +++ b/gfx/webrender_api/src/api.rs @@ -17,54 +17,158 @@ use {WebGLCommand, WebGLContextId}; pub type TileSize = u16; +/// The resource updates for a given transaction (they must be applied in the same frame). #[derive(Clone, Deserialize, Serialize)] -pub enum ApiMsg { - AddRawFont(FontKey, Vec, u32), - AddNativeFont(FontKey, NativeFontHandle), - DeleteFont(FontKey), - /// Gets the glyph dimensions - GetGlyphDimensions(FontInstanceKey, Vec, MsgSender>>), - /// Gets the glyph indices from a string - GetGlyphIndices(FontKey, String, MsgSender>>), - /// Adds an image from the resource cache. - AddImage(ImageKey, ImageDescriptor, ImageData, Option), - /// Updates the the resource cache with the new image data. - UpdateImage(ImageKey, ImageDescriptor, ImageData, Option), - /// Drops an image from the resource cache. +pub struct ResourceUpdates { + pub updates: Vec, +} + +#[derive(Clone, Deserialize, Serialize)] +pub enum ResourceUpdate { + AddImage(AddImage), + UpdateImage(UpdateImage), DeleteImage(ImageKey), - CloneApi(MsgSender), - /// Supplies a new frame to WebRender. - /// - /// After receiving this message, WebRender will read the display list from the payload channel. - // TODO: We should consider using named members to avoid confusion. - SetDisplayList(Option, - Epoch, - PipelineId, - LayoutSize, // viewport_size - LayoutSize, // content size - BuiltDisplayListDescriptor, - bool), + AddFont(AddFont), + DeleteFont(FontKey), +} + +impl ResourceUpdates { + pub fn new() -> Self { + ResourceUpdates { + updates: Vec::new(), + } + } + + pub fn add_image( + &mut self, + key: ImageKey, + descriptor: ImageDescriptor, + data: ImageData, + tiling: Option + ) { + self.updates.push(ResourceUpdate::AddImage(AddImage { key, descriptor, data, tiling })); + } + + pub fn update_image( + &mut self, + key: ImageKey, + descriptor: ImageDescriptor, + data: ImageData, + dirty_rect: Option + ) { + self.updates.push(ResourceUpdate::UpdateImage(UpdateImage { key, descriptor, data, dirty_rect })); + } + + pub fn delete_image(&mut self, key: ImageKey) { + self.updates.push(ResourceUpdate::DeleteImage(key)); + } + + pub fn add_raw_font(&mut self, key: FontKey, bytes: Vec, index: u32) { + self.updates.push(ResourceUpdate::AddFont(AddFont::Raw(key, bytes, index))); + } + + pub fn add_native_font(&mut self, key: FontKey, native_handle: NativeFontHandle) { + self.updates.push(ResourceUpdate::AddFont(AddFont::Native(key, native_handle))); + } + + pub fn delete_font(&mut self, key: FontKey) { + self.updates.push(ResourceUpdate::DeleteFont(key)); + } +} + +#[derive(Clone, Deserialize, Serialize)] +pub struct AddImage { + pub key: ImageKey, + pub descriptor: ImageDescriptor, + pub data: ImageData, + pub tiling: Option, +} + +#[derive(Clone, Deserialize, Serialize)] +pub struct UpdateImage { + pub key: ImageKey, + pub descriptor: ImageDescriptor, + pub data: ImageData, + pub dirty_rect: Option, +} + +#[derive(Clone, Deserialize, Serialize)] +pub enum AddFont { + Raw(FontKey, Vec, u32), + Native(FontKey, NativeFontHandle), +} + +#[derive(Clone, Deserialize, Serialize)] +pub enum DocumentMsg { + SetDisplayList { + list_descriptor: BuiltDisplayListDescriptor, + epoch: Epoch, + pipeline_id: PipelineId, + background: Option, + viewport_size: LayoutSize, + content_size: LayoutSize, + preserve_frame_state: bool, + resources: ResourceUpdates, + }, SetPageZoom(ZoomFactor), SetPinchZoom(ZoomFactor), SetPan(DeviceIntPoint), SetRootPipeline(PipelineId), - SetWindowParameters(DeviceUintSize, DeviceUintRect), + SetWindowParameters { + window_size: DeviceUintSize, + inner_rect: DeviceUintRect, + }, Scroll(ScrollLocation, WorldPoint, ScrollEventPhase), ScrollNodeWithId(LayoutPoint, ClipId, ScrollClamping), TickScrollingBounce, - TranslatePointToLayerSpace(WorldPoint, MsgSender<(LayoutPoint, PipelineId)>), GetScrollNodeState(MsgSender>), + GenerateFrame(Option), +} + +impl fmt::Debug for DocumentMsg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(match *self { + DocumentMsg::SetDisplayList{..} => "DocumentMsg::SetDisplayList", + DocumentMsg::SetPageZoom(..) => "DocumentMsg::SetPageZoom", + DocumentMsg::SetPinchZoom(..) => "DocumentMsg::SetPinchZoom", + DocumentMsg::SetPan(..) => "DocumentMsg::SetPan", + DocumentMsg::SetRootPipeline(..) => "DocumentMsg::SetRootPipeline", + DocumentMsg::SetWindowParameters{..} => "DocumentMsg::SetWindowParameters", + DocumentMsg::Scroll(..) => "DocumentMsg::Scroll", + DocumentMsg::ScrollNodeWithId(..) => "DocumentMsg::ScrollNodeWithId", + DocumentMsg::TickScrollingBounce => "DocumentMsg::TickScrollingBounce", + DocumentMsg::GetScrollNodeState(..) => "DocumentMsg::GetScrollNodeState", + DocumentMsg::GenerateFrame(..) => "DocumentMsg::GenerateFrame", + }) + } +} + +#[derive(Clone, Deserialize, Serialize)] +pub enum ApiMsg { + /// Add/remove/update images and fonts. + UpdateResources(ResourceUpdates), + /// Gets the glyph dimensions + GetGlyphDimensions(FontInstanceKey, Vec, MsgSender>>), + /// Gets the glyph indices from a string + GetGlyphIndices(FontKey, String, MsgSender>>), + /// Adds a new document namespace. + CloneApi(MsgSender), + /// Adds a new document with given initial size. + AddDocument(DocumentId, DeviceUintSize), + /// A message targeted at a particular document. + UpdateDocument(DocumentId, DocumentMsg), + /// Deletes an existing document. + DeleteDocument(DocumentId), RequestWebGLContext(DeviceIntSize, GLContextAttributes, MsgSender>), ResizeWebGLContext(WebGLContextId, DeviceIntSize), WebGLCommand(WebGLContextId, WebGLCommand), - GenerateFrame(Option), // WebVR commands that must be called in the WebGL render thread. VRCompositorCommand(WebGLContextId, VRCompositorCommand), /// An opaque handle that must be passed to the render notifier. It is used by Gecko /// to forward gecko-specific messages to the render thread preserving the ordering /// within the other messages. ExternalEvent(ExternalEvent), - /// Remove all resources associated with this namespace. + /// Removes all resources associated with a namespace. ClearNamespace(IdNamespace), ShutDown, } @@ -72,34 +176,20 @@ pub enum ApiMsg { impl fmt::Debug for ApiMsg { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str(match *self { - ApiMsg::AddRawFont(..) => "ApiMsg::AddRawFont", - ApiMsg::AddNativeFont(..) => "ApiMsg::AddNativeFont", - ApiMsg::DeleteFont(..) => "ApiMsg::DeleteFont", + ApiMsg::UpdateResources(..) => "ApiMsg::UpdateResources", ApiMsg::GetGlyphDimensions(..) => "ApiMsg::GetGlyphDimensions", ApiMsg::GetGlyphIndices(..) => "ApiMsg::GetGlyphIndices", - ApiMsg::AddImage(..) => "ApiMsg::AddImage", - ApiMsg::UpdateImage(..) => "ApiMsg::UpdateImage", - ApiMsg::DeleteImage(..) => "ApiMsg::DeleteImage", ApiMsg::CloneApi(..) => "ApiMsg::CloneApi", - ApiMsg::SetDisplayList(..) => "ApiMsg::SetDisplayList", - ApiMsg::SetRootPipeline(..) => "ApiMsg::SetRootPipeline", - ApiMsg::Scroll(..) => "ApiMsg::Scroll", - ApiMsg::ScrollNodeWithId(..) => "ApiMsg::ScrollNodeWithId", - ApiMsg::TickScrollingBounce => "ApiMsg::TickScrollingBounce", - ApiMsg::TranslatePointToLayerSpace(..) => "ApiMsg::TranslatePointToLayerSpace", - ApiMsg::GetScrollNodeState(..) => "ApiMsg::GetScrollNodeState", + ApiMsg::AddDocument(..) => "ApiMsg::AddDocument", + ApiMsg::UpdateDocument(..) => "ApiMsg::UpdateDocument", + ApiMsg::DeleteDocument(..) => "ApiMsg::DeleteDocument", ApiMsg::RequestWebGLContext(..) => "ApiMsg::RequestWebGLContext", ApiMsg::ResizeWebGLContext(..) => "ApiMsg::ResizeWebGLContext", ApiMsg::WebGLCommand(..) => "ApiMsg::WebGLCommand", - ApiMsg::GenerateFrame(..) => "ApiMsg::GenerateFrame", ApiMsg::VRCompositorCommand(..) => "ApiMsg::VRCompositorCommand", ApiMsg::ExternalEvent(..) => "ApiMsg::ExternalEvent", - ApiMsg::ShutDown => "ApiMsg::ShutDown", - ApiMsg::SetPageZoom(..) => "ApiMsg::SetPageZoom", - ApiMsg::SetPinchZoom(..) => "ApiMsg::SetPinchZoom", - ApiMsg::SetPan(..) => "ApiMsg::SetPan", - ApiMsg::SetWindowParameters(..) => "ApiMsg::SetWindowParameters", ApiMsg::ClearNamespace(..) => "ApiMsg::ClearNamespace", + ApiMsg::ShutDown => "ApiMsg::ShutDown", }) } } @@ -126,14 +216,33 @@ pub enum WebGLCommand { Flush, } -#[repr(C)] -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] -pub struct PipelineId(pub u32, pub u32); - #[repr(C)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)] pub struct IdNamespace(pub u32); +#[repr(C)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct DocumentId(pub IdNamespace, pub u32); + +/// This type carries no valuable semantics for WR. However, it reflects the fact that +/// clients (Servo) may generate pipelines by different semi-independent sources. +/// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`. +/// Having this extra Id field enables them to generate `PipelineId` without collision. +pub type PipelineSourceId = u32; + +/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as +/// it's clonable, serializable, comparable, and hashable. +#[repr(C)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub struct PipelineId(pub PipelineSourceId, pub u32); + +impl PipelineId { + pub fn dummy() -> Self { + PipelineId(0, 0) + } +} + + #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Serialize)] pub struct ResourceId(pub u32); @@ -168,60 +277,61 @@ pub struct RenderApiSender { impl RenderApiSender { pub fn new(api_sender: MsgSender, payload_sender: PayloadSender) - -> RenderApiSender { + -> Self { RenderApiSender { api_sender, payload_sender, } } + /// Creates a new resource API object with a dedicated namespace. pub fn create_api(&self) -> RenderApi { - let RenderApiSender { - ref api_sender, - ref payload_sender - } = *self; let (sync_tx, sync_rx) = channel::msg_channel().unwrap(); let msg = ApiMsg::CloneApi(sync_tx); - api_sender.send(msg).unwrap(); + self.api_sender.send(msg).unwrap(); RenderApi { - api_sender: api_sender.clone(), - payload_sender: payload_sender.clone(), - id_namespace: sync_rx.recv().unwrap(), + api_sender: self.api_sender.clone(), + payload_sender: self.payload_sender.clone(), + namespace_id: sync_rx.recv().unwrap(), next_id: Cell::new(ResourceId(0)), } } } pub struct RenderApi { - pub api_sender: MsgSender, - pub payload_sender: PayloadSender, - pub id_namespace: IdNamespace, - pub next_id: Cell, + api_sender: MsgSender, + payload_sender: PayloadSender, + namespace_id: IdNamespace, + next_id: Cell, } impl RenderApi { + pub fn get_namespace_id(&self) -> IdNamespace { + self.namespace_id + } + pub fn clone_sender(&self) -> RenderApiSender { RenderApiSender::new(self.api_sender.clone(), self.payload_sender.clone()) } + pub fn add_document(&self, initial_size: DeviceUintSize) -> DocumentId { + let new_id = self.next_unique_id(); + let document_id = DocumentId(self.namespace_id, new_id); + + let msg = ApiMsg::AddDocument(document_id, initial_size); + self.api_sender.send(msg).unwrap(); + + document_id + } + + pub fn delete_document(&self, document_id: DocumentId) { + let msg = ApiMsg::DeleteDocument(document_id); + self.api_sender.send(msg).unwrap(); + } + pub fn generate_font_key(&self) -> FontKey { let new_id = self.next_unique_id(); - FontKey::new(new_id.0, new_id.1) - } - - pub fn add_raw_font(&self, key: FontKey, bytes: Vec, index: u32) { - let msg = ApiMsg::AddRawFont(key, bytes, index); - self.api_sender.send(msg).unwrap(); - } - - pub fn add_native_font(&self, key: FontKey, native_font_handle: NativeFontHandle) { - let msg = ApiMsg::AddNativeFont(key, native_font_handle); - self.api_sender.send(msg).unwrap(); - } - - pub fn delete_font(&self, key: FontKey) { - let msg = ApiMsg::DeleteFont(key); - self.api_sender.send(msg).unwrap(); + FontKey::new(self.namespace_id, new_id) } /// Gets the dimensions for the supplied glyph keys @@ -253,155 +363,12 @@ impl RenderApi { /// Creates an `ImageKey`. pub fn generate_image_key(&self) -> ImageKey { let new_id = self.next_unique_id(); - ImageKey::new(new_id.0, new_id.1) + ImageKey::new(self.namespace_id, new_id) } /// Adds an image identified by the `ImageKey`. - pub fn add_image(&self, - key: ImageKey, - descriptor: ImageDescriptor, - data: ImageData, - tiling: Option) { - let msg = ApiMsg::AddImage(key, descriptor, data, tiling); - self.api_sender.send(msg).unwrap(); - } - - /// Updates a specific image. - /// - /// Currently doesn't support changing dimensions or format by updating. - // TODO: Support changing dimensions (and format) during image update? - pub fn update_image(&self, - key: ImageKey, - descriptor: ImageDescriptor, - data: ImageData, - dirty_rect: Option) { - let msg = ApiMsg::UpdateImage(key, descriptor, data, dirty_rect); - self.api_sender.send(msg).unwrap(); - } - - /// Deletes the specific image. - pub fn delete_image(&self, key: ImageKey) { - let msg = ApiMsg::DeleteImage(key); - self.api_sender.send(msg).unwrap(); - } - - /// Sets the root pipeline. - /// - /// # Examples - /// - /// ``` - /// # use webrender_api::{PipelineId, RenderApiSender}; - /// # fn example(sender: RenderApiSender) { - /// let api = sender.create_api(); - /// // ... - /// let pipeline_id = PipelineId(0, 0); - /// api.set_root_pipeline(pipeline_id); - /// # } - /// ``` - pub fn set_root_pipeline(&self, pipeline_id: PipelineId) { - let msg = ApiMsg::SetRootPipeline(pipeline_id); - self.api_sender.send(msg).unwrap(); - } - - /// Supplies a new frame to WebRender. - /// - /// Non-blocking, it notifies a worker process which processes the display list. - /// When it's done and a RenderNotifier has been set in `webrender::renderer::Renderer`, - /// [new_frame_ready()][notifier] gets called. - /// - /// Note: Scrolling doesn't require an own Frame. - /// - /// Arguments: - /// - /// * `background_color`: The background color of this pipeline. - /// * `epoch`: The unique Frame ID, monotonically increasing. - /// * `viewport_size`: The size of the viewport for this frame. - /// * `pipeline_id`: The ID of the pipeline that is supplying this display list. - /// * `content_size`: The total screen space size of this display list's display items. - /// * `display_list`: The root Display list used in this frame. - /// * `preserve_frame_state`: If a previous frame exists which matches this pipeline - /// id, this setting determines if frame state (such as scrolling - /// position) should be preserved for this new display list. - /// - /// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready - pub fn set_display_list(&self, - background_color: Option, - epoch: Epoch, - viewport_size: LayoutSize, - (pipeline_id, content_size, display_list): (PipelineId, LayoutSize, BuiltDisplayList), - preserve_frame_state: bool) { - let (display_list_data, display_list_descriptor) = display_list.into_data(); - let msg = ApiMsg::SetDisplayList(background_color, - epoch, - pipeline_id, - viewport_size, - content_size, - display_list_descriptor, - preserve_frame_state); - self.api_sender.send(msg).unwrap(); - - self.payload_sender.send_payload(Payload { - epoch, - pipeline_id, - display_list_data, - }).unwrap(); - } - - /// Scrolls the scrolling layer under the `cursor` - /// - /// WebRender looks for the layer closest to the user - /// which has `ScrollPolicy::Scrollable` set. - pub fn scroll(&self, scroll_location: ScrollLocation, cursor: WorldPoint, phase: ScrollEventPhase) { - let msg = ApiMsg::Scroll(scroll_location, cursor, phase); - self.api_sender.send(msg).unwrap(); - } - - pub fn scroll_node_with_id(&self, origin: LayoutPoint, id: ClipId, clamp: ScrollClamping) { - let msg = ApiMsg::ScrollNodeWithId(origin, id, clamp); - self.api_sender.send(msg).unwrap(); - } - - pub fn set_page_zoom(&self, page_zoom: ZoomFactor) { - let msg = ApiMsg::SetPageZoom(page_zoom); - self.api_sender.send(msg).unwrap(); - } - - pub fn set_pinch_zoom(&self, pinch_zoom: ZoomFactor) { - let msg = ApiMsg::SetPinchZoom(pinch_zoom); - self.api_sender.send(msg).unwrap(); - } - - pub fn set_pan(&self, pan: DeviceIntPoint) { - let msg = ApiMsg::SetPan(pan); - self.api_sender.send(msg).unwrap(); - } - - pub fn set_window_parameters(&self, - window_size: DeviceUintSize, - inner_rect: DeviceUintRect) { - let msg = ApiMsg::SetWindowParameters(window_size, inner_rect); - self.api_sender.send(msg).unwrap(); - } - - pub fn tick_scrolling_bounce_animations(&self) { - let msg = ApiMsg::TickScrollingBounce; - self.api_sender.send(msg).unwrap(); - } - - /// Translates a point from viewport coordinates to layer space - pub fn translate_point_to_layer_space(&self, point: &WorldPoint) - -> (LayoutPoint, PipelineId) { - let (tx, rx) = channel::msg_channel().unwrap(); - let msg = ApiMsg::TranslatePointToLayerSpace(*point, tx); - self.api_sender.send(msg).unwrap(); - rx.recv().unwrap() - } - - pub fn get_scroll_node_state(&self) -> Vec { - let (tx, rx) = channel::msg_channel().unwrap(); - let msg = ApiMsg::GetScrollNodeState(tx); - self.api_sender.send(msg).unwrap(); - rx.recv().unwrap() + pub fn update_resources(&self, resources: ResourceUpdates) { + self.api_sender.send(ApiMsg::UpdateResources(resources)).unwrap(); } pub fn request_webgl_context(&self, size: &DeviceIntSize, attributes: GLContextAttributes) @@ -422,14 +389,6 @@ impl RenderApi { self.api_sender.send(msg).unwrap(); } - /// Generate a new frame. Optionally, supply a list of animated - /// property bindings that should be used to resolve bindings - /// in the current display list. - pub fn generate_frame(&self, property_bindings: Option) { - let msg = ApiMsg::GenerateFrame(property_bindings); - self.api_sender.send(msg).unwrap(); - } - pub fn send_vr_compositor_command(&self, context_id: WebGLContextId, command: VRCompositorCommand) { let msg = ApiMsg::VRCompositorCommand(context_id, command); self.api_sender.send(msg).unwrap(); @@ -450,24 +409,169 @@ impl RenderApi { let new_id = self.next_unique_id(); PropertyBindingKey { id: PropertyBindingId { - namespace: new_id.0, - uid: new_id.1, + namespace: self.namespace_id, + uid: new_id, }, _phantom: PhantomData, } } #[inline] - fn next_unique_id(&self) -> (IdNamespace, u32) { + fn next_unique_id(&self) -> u32 { let ResourceId(id) = self.next_id.get(); self.next_id.set(ResourceId(id + 1)); - (self.id_namespace, id) + id + } + + // For use in Wrench only + #[doc(hidden)] + pub fn send_message(&self, msg: ApiMsg) { + self.api_sender.send(msg).unwrap(); + } + + // For use in Wrench only + #[doc(hidden)] + pub fn send_payload(&self, data: &[u8]) { + self.payload_sender.send_payload(Payload::from_data(data)).unwrap(); + } + + /// A helper method to send document messages. + fn send(&self, document_id: DocumentId, msg: DocumentMsg) { + // This assertion fails on Servo use-cases, because it creates different + // `RenderApi` instances for layout and compositor. + //assert_eq!(document_id.0, self.namespace_id); + self.api_sender.send(ApiMsg::UpdateDocument(document_id, msg)).unwrap() + } + + /// Sets the root pipeline. + /// + /// # Examples + /// + /// ``` + /// # use webrender_api::{DeviceUintSize, PipelineId, RenderApiSender}; + /// # fn example(sender: RenderApiSender) { + /// let api = sender.create_api(); + /// let document_id = api.add_document(DeviceUintSize::zero()); + /// let pipeline_id = PipelineId(0, 0); + /// api.set_root_pipeline(document_id, pipeline_id); + /// # } + /// ``` + pub fn set_root_pipeline(&self, document_id: DocumentId, pipeline_id: PipelineId) { + self.send(document_id, DocumentMsg::SetRootPipeline(pipeline_id)); + } + + /// Supplies a new frame to WebRender. + /// + /// Non-blocking, it notifies a worker process which processes the display list. + /// When it's done and a RenderNotifier has been set in `webrender::renderer::Renderer`, + /// [new_frame_ready()][notifier] gets called. + /// + /// Note: Scrolling doesn't require an own Frame. + /// + /// Arguments: + /// + /// * `document_id`: Target Document ID. + /// * `epoch`: The unique Frame ID, monotonically increasing. + /// * `background`: The background color of this pipeline. + /// * `viewport_size`: The size of the viewport for this frame. + /// * `pipeline_id`: The ID of the pipeline that is supplying this display list. + /// * `content_size`: The total screen space size of this display list's display items. + /// * `display_list`: The root Display list used in this frame. + /// * `preserve_frame_state`: If a previous frame exists which matches this pipeline + /// id, this setting determines if frame state (such as scrolling + /// position) should be preserved for this new display list. + /// * `resources`: A set of resource updates that must be applied at the same time as the + /// display list. + /// + /// [notifier]: trait.RenderNotifier.html#tymethod.new_frame_ready + pub fn set_display_list( + &self, + document_id: DocumentId, + epoch: Epoch, + background: Option, + viewport_size: LayoutSize, + (pipeline_id, content_size, display_list): (PipelineId, LayoutSize, BuiltDisplayList), + preserve_frame_state: bool, + resources: ResourceUpdates, + ) { + let (display_list_data, list_descriptor) = display_list.into_data(); + self.send(document_id, DocumentMsg::SetDisplayList { + epoch, + pipeline_id, + background, + viewport_size, + content_size, + list_descriptor, + preserve_frame_state, + resources, + }); + + self.payload_sender.send_payload(Payload { + epoch, + pipeline_id, + display_list_data, + }).unwrap(); + } + + /// Scrolls the scrolling layer under the `cursor` + /// + /// WebRender looks for the layer closest to the user + /// which has `ScrollPolicy::Scrollable` set. + pub fn scroll(&self, document_id: DocumentId, scroll_location: ScrollLocation, + cursor: WorldPoint, phase: ScrollEventPhase) { + self.send(document_id, DocumentMsg::Scroll(scroll_location, cursor, phase)); + } + + pub fn scroll_node_with_id(&self, document_id: DocumentId, origin: LayoutPoint, + id: ClipId, clamp: ScrollClamping) { + self.send(document_id, DocumentMsg::ScrollNodeWithId(origin, id, clamp)); + } + + pub fn set_page_zoom(&self, document_id: DocumentId, page_zoom: ZoomFactor) { + self.send(document_id, DocumentMsg::SetPageZoom(page_zoom)); + } + + pub fn set_pinch_zoom(&self, document_id: DocumentId, pinch_zoom: ZoomFactor) { + self.send(document_id, DocumentMsg::SetPinchZoom(pinch_zoom)); + } + + pub fn set_pan(&self, document_id: DocumentId, pan: DeviceIntPoint) { + self.send(document_id, DocumentMsg::SetPan(pan)); + } + + pub fn set_window_parameters(&self, + document_id: DocumentId, + window_size: DeviceUintSize, + inner_rect: DeviceUintRect) { + self.send(document_id, DocumentMsg::SetWindowParameters { + window_size, + inner_rect, + }); + } + + pub fn tick_scrolling_bounce_animations(&self, document_id: DocumentId) { + self.send(document_id, DocumentMsg::TickScrollingBounce); + } + + pub fn get_scroll_node_state(&self, document_id: DocumentId) -> Vec { + let (tx, rx) = channel::msg_channel().unwrap(); + self.send(document_id, DocumentMsg::GetScrollNodeState(tx)); + rx.recv().unwrap() + } + + /// Generate a new frame. Optionally, supply a list of animated + /// property bindings that should be used to resolve bindings + /// in the current display list. + pub fn generate_frame(&self, document_id: DocumentId, + property_bindings: Option) { + self.send(document_id, DocumentMsg::GenerateFrame(property_bindings)); } } impl Drop for RenderApi { fn drop(&mut self) { - let _ = self.api_sender.send(ApiMsg::ClearNamespace(self.id_namespace)); + let msg = ApiMsg::ClearNamespace(self.namespace_id); + let _ = self.api_sender.send(msg); } } diff --git a/gfx/webrender_api/src/color.rs b/gfx/webrender_api/src/color.rs index dc3012641790..1117fe55e51a 100644 --- a/gfx/webrender_api/src/color.rs +++ b/gfx/webrender_api/src/color.rs @@ -2,6 +2,8 @@ * 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 std::hash::{Hash, Hasher}; + /// Represents RGBA screen colors with floating point numbers. /// /// All components must be between 0.0 and 1.0. @@ -50,6 +52,26 @@ impl ColorF { } } +// Floats don't impl Hash/Eq... +impl Eq for ColorF { } +impl Hash for ColorF { + fn hash(&self, state: &mut H) { + // Note: this is inconsistent with the Eq impl for -0.0 (don't care). + self.r._to_bits().hash(state); + self.g._to_bits().hash(state); + self.b._to_bits().hash(state); + self.a._to_bits().hash(state); + } +} + +// FIXME: remove this when Rust 1.21 is stable (float_bits_conv) +trait ToBits { + fn _to_bits(self) -> u32; +} +impl ToBits for f32 { + fn _to_bits(self) -> u32 { unsafe { ::std::mem::transmute(self) } } +} + /// Represents RGBA screen colors with one byte per channel. /// /// If the alpha value `a` is 255 the color is opaque. diff --git a/gfx/webrender_api/src/display_item.rs b/gfx/webrender_api/src/display_item.rs index 85c361b14ace..d31265773803 100644 --- a/gfx/webrender_api/src/display_item.rs +++ b/gfx/webrender_api/src/display_item.rs @@ -670,3 +670,4 @@ define_empty_heap_size_of!(MixBlendMode); define_empty_heap_size_of!(TransformStyle); define_empty_heap_size_of!(LocalClip); define_empty_heap_size_of!(ScrollSensitivity); +define_empty_heap_size_of!(ClipAndScrollInfo); diff --git a/gfx/webrender_api/src/display_list.rs b/gfx/webrender_api/src/display_list.rs index 7040bf47ab2a..528abbfec798 100644 --- a/gfx/webrender_api/src/display_list.rs +++ b/gfx/webrender_api/src/display_list.rs @@ -9,14 +9,15 @@ use serde::ser::{SerializeSeq, SerializeMap}; use time::precise_time_ns; use {BorderDetails, BorderDisplayItem, BorderWidths, BoxShadowClipMode, BoxShadowDisplayItem}; use {ClipAndScrollInfo, ClipDisplayItem, ClipId, ColorF, ComplexClipRegion, DisplayItem}; -use {ExtendMode, FilterOp, FontKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem}; -use {GradientStop, IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering}; -use {LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineDisplayItem}; -use {LineOrientation, LineStyle, LocalClip, MixBlendMode, PipelineId, PropertyBinding}; -use {PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem}; +use {ExtendMode, FilterOp, FontKey, GlyphIndex, GlyphInstance, GlyphOptions, Gradient}; +use {GradientDisplayItem, GradientStop, IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask}; +use {ImageRendering, LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; +use {LineDisplayItem, LineOrientation, LineStyle, LocalClip, MixBlendMode, PipelineId}; +use {PropertyBinding, PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem}; use {RectangleDisplayItem, ScrollFrameDisplayItem, ScrollPolicy, ScrollSensitivity}; use {SpecificDisplayItem, StackingContext, TextDisplayItem, TextShadow, TransformStyle}; use {WebGLContextId, WebGLDisplayItem, YuvColorSpace, YuvData, YuvImageDisplayItem}; +use {FastHashMap, FastHashSet}; use std::marker::PhantomData; #[repr(C)] @@ -61,6 +62,8 @@ pub struct BuiltDisplayListDescriptor { builder_finish_time: u64, /// The third IPC time stamp: just before sending send_start_time: u64, + /// The offset where DisplayItems stop and the Glyph list starts + glyph_offset: usize, } pub struct BuiltDisplayListIter<'a> { @@ -78,6 +81,12 @@ pub struct DisplayItemRef<'a: 'b, 'b> { iter: &'b BuiltDisplayListIter<'a>, } +pub struct GlyphsIter<'a> { + list: &'a BuiltDisplayList, + data: &'a [u8], +} + + #[derive(PartialEq)] enum Peek { StartPeeking, @@ -112,6 +121,14 @@ impl BuiltDisplayList { &self.data[..] } + pub fn item_slice(&self) -> &[u8] { + &self.data[..self.descriptor.glyph_offset] + } + + pub fn glyph_slice(&self) -> &[u8] { + &self.data[self.descriptor.glyph_offset..] + } + pub fn descriptor(&self) -> &BuiltDisplayListDescriptor { &self.descriptor } @@ -126,14 +143,40 @@ impl BuiltDisplayList { BuiltDisplayListIter::new(self) } + pub fn glyphs(&self) -> GlyphsIter { + GlyphsIter { + list: self, + data: self.glyph_slice(), + } + } + pub fn get<'de, T: Deserialize<'de>>(&self, range: ItemRange) -> AuxIter { AuxIter::new(&self.data[range.start .. range.start + range.length]) } } +/// Returns the byte-range the slice occupied, and the number of elements +/// in the slice. +fn skip_slice Deserialize<'de>>(list: &BuiltDisplayList, data: &mut &[u8]) -> (ItemRange, usize) { + let base = list.data.as_ptr() as usize; + let start = data.as_ptr() as usize; + + // Read through the values (this is a bit of a hack to reuse logic) + let mut iter = AuxIter::::new(*data); + let count = iter.len(); + for _ in &mut iter {} + let end = iter.data.as_ptr() as usize; + + let range = ItemRange { start: start - base, length: end - start, _boo: PhantomData }; + + // Adjust data pointer to skip read values + *data = &data[range.length..]; + (range, count) +} + impl<'a> BuiltDisplayListIter<'a> { pub fn new(list: &'a BuiltDisplayList) -> Self { - Self::new_with_list_and_data(list, &list.data) + Self::new_with_list_and_data(list, list.item_slice()) } pub fn new_with_list_and_data(list: &'a BuiltDisplayList, data: &'a [u8]) -> Self { @@ -144,7 +187,7 @@ impl<'a> BuiltDisplayListIter<'a> { item: SpecificDisplayItem::PopStackingContext, rect: LayoutRect::zero(), local_clip: LocalClip::from(LayoutRect::zero()), - clip_and_scroll: ClipAndScrollInfo::simple(ClipId::new(0, PipelineId(0, 0))), + clip_and_scroll: ClipAndScrollInfo::simple(ClipId::new(0, PipelineId::dummy())), }, cur_stops: ItemRange::default(), cur_glyphs: ItemRange::default(), @@ -186,7 +229,7 @@ impl<'a> BuiltDisplayListIter<'a> { match self.cur_item.item { SetGradientStops => { - self.cur_stops = self.skip_slice::().0; + self.cur_stops = skip_slice::(self.list, &mut self.data).0; // This is a dummy item, skip over it continue; @@ -204,23 +247,8 @@ impl<'a> BuiltDisplayListIter<'a> { Some(self.as_ref()) } - /// Returns the byte-range the slice occupied, and the number of elements - /// in the slice. fn skip_slice Deserialize<'de>>(&mut self) -> (ItemRange, usize) { - let base = self.list.data.as_ptr() as usize; - let start = self.data.as_ptr() as usize; - - // Read through the values (this is a bit of a hack to reuse logic) - let mut iter = AuxIter::::new(self.data); - let count = iter.len(); - for _ in &mut iter {} - let end = iter.data.as_ptr() as usize; - - let range = ItemRange { start: start - base, length: end - start, _boo: PhantomData }; - - // Adjust data pointer to skip read values - self.data = &self.data[range.length..]; - (range, count) + skip_slice::(self.list, &mut self.data) } pub fn as_ref<'b>(&'b self) -> DisplayItemRef<'a, 'b> { @@ -268,6 +296,19 @@ impl<'a> BuiltDisplayListIter<'a> { } } +impl<'a> Iterator for GlyphsIter<'a> { + type Item = (FontKey, ColorF, ItemRange); + + fn next(&mut self) -> Option { + if self.data.len() == 0 { return None; } + + let (font_key, color) = bincode::deserialize_from(&mut self.data, bincode::Infinite) + .expect("MEH: malicious process?"); + let glyph_indices = skip_slice::(self.list, &mut self.data).0; + Some((font_key, color, glyph_indices)) + } +} + // Some of these might just become ItemRanges impl<'a, 'b> DisplayItemRef<'a, 'b> { pub fn display_item(&self) -> &DisplayItem { @@ -411,6 +452,8 @@ pub struct DisplayListBuilder { pub data: Vec, pub pipeline_id: PipelineId, clip_stack: Vec, + // FIXME: audit whether fast hashers (FNV?) are safe here + glyphs: FastHashMap<(FontKey, ColorF), FastHashSet>, next_clip_id: u64, builder_start_time: u64, @@ -436,6 +479,7 @@ impl DisplayListBuilder { data: Vec::with_capacity(capacity), pipeline_id, clip_stack: vec![ClipAndScrollInfo::simple(ClipId::root_scroll_node(pipeline_id))], + glyphs: FastHashMap::default(), next_clip_id: FIRST_CLIP_ID, builder_start_time: start_time, content_size, @@ -587,9 +631,22 @@ impl DisplayListBuilder { self.push_item(item, rect, local_clip); self.push_iter(glyphs); + + // Remember that we've seen these glyphs + self.cache_glyphs(font_key, color, glyphs.iter().map(|glyph| glyph.index)); } } + fn cache_glyphs>(&mut self, + font_key: FontKey, + color: ColorF, + glyphs: I) { + let mut font_glyphs = self.glyphs.entry((font_key, color)) + .or_insert(FastHashSet::default()); + + font_glyphs.extend(glyphs); + } + // Gradients can be defined with stops outside the range of [0, 1] // when this happens the gradient needs to be normalized by adjusting // the gradient stops and gradient line into an equivalent gradient @@ -940,7 +997,14 @@ impl DisplayListBuilder { // id. pub fn push_nested_display_list(&mut self, built_display_list: &BuiltDisplayList) { self.push_new_empty_item(SpecificDisplayItem::PushNestedDisplayList); - self.data.extend_from_slice(&built_display_list.data); + + // Need to read out all the glyph data to update the cache + for (font_key, color, glyphs) in built_display_list.glyphs() { + self.cache_glyphs(font_key, color, built_display_list.get(glyphs)); + } + + // Only append the actual items, not any caches + self.data.extend_from_slice(built_display_list.item_slice()); self.push_new_empty_item(SpecificDisplayItem::PopNestedDisplayList); } @@ -957,9 +1021,23 @@ impl DisplayListBuilder { self.push_new_empty_item(SpecificDisplayItem::PopTextShadow); } - pub fn finalize(self) -> (PipelineId, LayoutSize, BuiltDisplayList) { + pub fn finalize(mut self) -> (PipelineId, LayoutSize, BuiltDisplayList) { + + let glyph_offset = self.data.len(); + + // Want to use self.push_iter, so can't borrow self + let glyphs = ::std::mem::replace(&mut self.glyphs, FastHashMap::default()); + + // Append glyph data to the end + for ((font_key, color), sub_glyphs) in glyphs { + bincode::serialize_into(&mut self.data, &font_key, bincode::Infinite).unwrap(); + bincode::serialize_into(&mut self.data, &color, bincode::Infinite).unwrap(); + self.push_iter(sub_glyphs); + } + let end_time = precise_time_ns(); + (self.pipeline_id, self.content_size, BuiltDisplayList { @@ -967,6 +1045,7 @@ impl DisplayListBuilder { builder_start_time: self.builder_start_time, builder_finish_time: end_time, send_start_time: 0, + glyph_offset, }, data: self.data, }) diff --git a/gfx/webrender_api/src/font.rs b/gfx/webrender_api/src/font.rs index 8a20f3596352..5a2089a67942 100644 --- a/gfx/webrender_api/src/font.rs +++ b/gfx/webrender_api/src/font.rs @@ -80,6 +80,14 @@ pub enum FontRenderMode { Subpixel, } +#[repr(C)] +#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)] +pub enum SubpixelDirection { + None = 0, + Horizontal, + Vertical, +} + const FIXED16_SHIFT: i32 = 16; // This matches the behaviour of SkScalarToFixed @@ -92,10 +100,6 @@ impl FontRenderMode { // Skia quantizes subpixel offets into 1/4 increments. // Given the absolute position, return the quantized increment fn subpixel_quantize_offset(&self, pos: f32) -> SubpixelOffset { - if *self != FontRenderMode::Subpixel { - return SubpixelOffset::Zero; - } - const SUBPIXEL_BITS: i32 = 2; const SUBPIXEL_FIXED16_MASK: i32 = ((1 << SUBPIXEL_BITS) - 1) << (FIXED16_SHIFT - SUBPIXEL_BITS); @@ -133,26 +137,6 @@ impl Into for SubpixelOffset { } } -#[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)] -pub struct SubpixelPoint { - pub x: SubpixelOffset, - pub y: SubpixelOffset, -} - -impl SubpixelPoint { - pub fn new(point: LayoutPoint, - render_mode: FontRenderMode) -> SubpixelPoint { - SubpixelPoint { - x: render_mode.subpixel_quantize_offset(point.x), - y: render_mode.subpixel_quantize_offset(point.y), - } - } - - pub fn to_f64(&self) -> (f64, f64) { - (self.x.into(), self.y.into()) - } -} - #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)] pub struct GlyphOptions { // These are currently only used on windows for dwrite fonts. @@ -172,6 +156,7 @@ pub struct FontInstanceKey { pub color: ColorU, pub render_mode: FontRenderMode, pub glyph_options: Option, + pub subpx_dir: SubpixelDirection, } impl FontInstanceKey { @@ -179,7 +164,8 @@ impl FontInstanceKey { size: Au, mut color: ColorF, render_mode: FontRenderMode, - glyph_options: Option) -> FontInstanceKey { + glyph_options: Option, + subpx_dir: SubpixelDirection) -> FontInstanceKey { // In alpha/mono mode, the color of the font is irrelevant. // Forcing it to black in those cases saves rasterizing glyphs // of different colors when not needed. @@ -193,6 +179,15 @@ impl FontInstanceKey { color: color.into(), render_mode, glyph_options, + subpx_dir, + } + } + + pub fn get_subpx_offset(&self, glyph: &GlyphKey) -> (f64, f64) { + match self.subpx_dir { + SubpixelDirection::None => (0.0, 0.0), + SubpixelDirection::Horizontal => (glyph.subpixel_offset.into(), 0.0), + SubpixelDirection::Vertical => (0.0, glyph.subpixel_offset.into()), } } } @@ -200,23 +195,32 @@ impl FontInstanceKey { #[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)] pub struct GlyphKey { pub index: u32, - pub subpixel_point: SubpixelPoint, + pub subpixel_offset: SubpixelOffset, } impl GlyphKey { pub fn new(index: u32, point: LayoutPoint, - render_mode: FontRenderMode) -> GlyphKey { + render_mode: FontRenderMode, + subpx_dir: SubpixelDirection) -> GlyphKey { + let pos = match subpx_dir { + SubpixelDirection::None => 0.0, + SubpixelDirection::Horizontal => point.x, + SubpixelDirection::Vertical => point.y, + }; + GlyphKey { index, - subpixel_point: SubpixelPoint::new(point, render_mode), + subpixel_offset: render_mode.subpixel_quantize_offset(pos), } } } +pub type GlyphIndex = u32; + #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub struct GlyphInstance { - pub index: u32, + pub index: GlyphIndex, pub point: LayoutPoint, } diff --git a/gfx/webrender_api/src/lib.rs b/gfx/webrender_api/src/lib.rs index b06ad1d81261..6e9d3568f29e 100644 --- a/gfx/webrender_api/src/lib.rs +++ b/gfx/webrender_api/src/lib.rs @@ -11,6 +11,7 @@ extern crate byteorder; #[cfg(feature = "nightly")] extern crate core; extern crate euclid; +extern crate fxhash; extern crate gleam; #[macro_use] extern crate heapsize; @@ -51,3 +52,8 @@ pub use image::*; pub use units::*; #[cfg(feature = "webgl")] pub use webgl::*; + +use std::hash::BuildHasherDefault; +use std::collections::{HashMap, HashSet}; +type FastHashMap = HashMap>; +type FastHashSet = HashSet>; From c18e91b352cd185f670152820b122ae3742eb249 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:24 -0400 Subject: [PATCH 031/166] Bug 1385003 - Update webrender bindings for API changes in WR cset f6d81d9. r=kvark In theory the upstream API change should allow us to share the same WR renderer instance across multiple WebRenderAPI instances. For now however I retain the existing behaviour of one WR instance for each WebRenderAPI instance, but keep track of the document id in a new DocumentHandle struct. The C++ side keeps a pointer to this DocumentHandle struct instead of the raw RenderApi. MozReview-Commit-ID: I9pCKOY1OYx --HG-- extra : rebase_source : 7b0ae2ccb2692a76045371ac165468c7f7539b40 --- gfx/webrender_bindings/WebRenderAPI.cpp | 58 ++++----- gfx/webrender_bindings/WebRenderAPI.h | 6 +- gfx/webrender_bindings/src/bindings.rs | 157 ++++++++++++++---------- 3 files changed, 121 insertions(+), 100 deletions(-) diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index a666578c282a..39b866648a08 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -23,7 +23,7 @@ using layers::Stringify; class NewRenderer : public RendererEvent { public: - NewRenderer(wr::RenderApi** aApi, layers::CompositorBridgeParentBase* aBridge, + NewRenderer(wr::DocumentHandle** aDocHandle, layers::CompositorBridgeParentBase* aBridge, GLint* aMaxTextureSize, bool* aUseANGLE, RefPtr&& aWidget, @@ -31,7 +31,7 @@ public: bool aEnableProfiler, LayoutDeviceIntSize aSize, layers::SyncHandle* aHandle) - : mRenderApi(aApi) + : mDocHandle(aDocHandle) , mMaxTextureSize(aMaxTextureSize) , mUseANGLE(aUseANGLE) , mBridge(aBridge) @@ -75,7 +75,7 @@ public: wr::Renderer* wrRenderer = nullptr; if (!wr_window_new(aWindowId, mSize.width, mSize.height, gl.get(), aRenderThread.ThreadPool().Raw(), - this->mEnableProfiler, mRenderApi, &wrRenderer)) { + this->mEnableProfiler, mDocHandle, &wrRenderer)) { // wr_window_new puts a message into gfxCriticalNote if it returns false return; } @@ -104,7 +104,7 @@ public: } private: - wr::RenderApi** mRenderApi; + wr::DocumentHandle** mDocHandle; GLint* mMaxTextureSize; bool* mUseANGLE; layers::CompositorBridgeParentBase* mBridge; @@ -153,32 +153,32 @@ WebRenderAPI::Create(bool aEnableProfiler, static uint64_t sNextId = 1; auto id = NewWindowId(sNextId++); - wr::RenderApi* renderApi = nullptr; + wr::DocumentHandle* docHandle = nullptr; GLint maxTextureSize = 0; bool useANGLE = false; layers::SyncHandle syncHandle = 0; - // Dispatch a synchronous task because the RenderApi object needs to be created + // Dispatch a synchronous task because the DocumentHandle object needs to be created // on the render thread. If need be we could delay waiting on this task until - // the next time we need to access the RenderApi object. + // the next time we need to access the DocumentHandle object. layers::SynchronousTask task("Create Renderer"); - auto event = MakeUnique(&renderApi, aBridge, &maxTextureSize, &useANGLE, + auto event = MakeUnique(&docHandle, aBridge, &maxTextureSize, &useANGLE, Move(aWidget), &task, aEnableProfiler, aSize, &syncHandle); RenderThread::Get()->RunEvent(id, Move(event)); task.Wait(); - if (!renderApi) { + if (!docHandle) { return nullptr; } - return RefPtr(new WebRenderAPI(renderApi, id, maxTextureSize, useANGLE, syncHandle)).forget(); + return RefPtr(new WebRenderAPI(docHandle, id, maxTextureSize, useANGLE, syncHandle)).forget(); } wr::WrIdNamespace WebRenderAPI::GetNamespace() { - return wr_api_get_namespace(mRenderApi); + return wr_api_get_namespace(mDocHandle); } WebRenderAPI::~WebRenderAPI() @@ -188,7 +188,7 @@ WebRenderAPI::~WebRenderAPI() RunOnRenderThread(Move(event)); task.Wait(); - wr_api_delete(mRenderApi); + wr_api_delete(mDocHandle); } void @@ -196,20 +196,20 @@ WebRenderAPI::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId, const layers::FrameMetrics::ViewID& aScrollId, const wr::LayoutPoint& aScrollPosition) { - wr_scroll_layer_with_id(mRenderApi, aPipelineId, aScrollId, aScrollPosition); + wr_scroll_layer_with_id(mDocHandle, aPipelineId, aScrollId, aScrollPosition); } void WebRenderAPI::GenerateFrame() { - wr_api_generate_frame(mRenderApi); + wr_api_generate_frame(mDocHandle); } void WebRenderAPI::GenerateFrame(const nsTArray& aOpacityArray, const nsTArray& aTransformArray) { - wr_api_generate_frame_with_properties(mRenderApi, + wr_api_generate_frame_with_properties(mDocHandle, aOpacityArray.IsEmpty() ? nullptr : aOpacityArray.Elements(), aOpacityArray.Length(), @@ -228,7 +228,7 @@ WebRenderAPI::SetRootDisplayList(gfx::Color aBgColor, uint8_t *dl_data, size_t dl_size) { - wr_api_set_root_display_list(mRenderApi, + wr_api_set_root_display_list(mDocHandle, ToColorF(aBgColor), aEpoch, aViewportSize.width, aViewportSize.height, @@ -243,13 +243,13 @@ void WebRenderAPI::ClearRootDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id) { - wr_api_clear_root_display_list(mRenderApi, aEpoch, pipeline_id); + wr_api_clear_root_display_list(mDocHandle, aEpoch, pipeline_id); } void WebRenderAPI::SetWindowParameters(LayoutDeviceIntSize size) { - wr_api_set_window_parameters(mRenderApi, size.width, size.height); + wr_api_set_window_parameters(mDocHandle, size.width, size.height); } void @@ -411,14 +411,14 @@ WebRenderAPI::WaitFlushed() void WebRenderAPI::SetRootPipeline(PipelineId aPipeline) { - wr_api_set_root_pipeline(mRenderApi, aPipeline); + wr_api_set_root_pipeline(mDocHandle, aPipeline); } void WebRenderAPI::AddImage(ImageKey key, const ImageDescriptor& aDescriptor, Range aBytes) { - wr_api_add_image(mRenderApi, + wr_api_add_image(mDocHandle, key, &aDescriptor, RangeToByteSlice(aBytes)); @@ -428,7 +428,7 @@ void WebRenderAPI::AddBlobImage(ImageKey key, const ImageDescriptor& aDescriptor, Range aBytes) { - wr_api_add_blob_image(mRenderApi, + wr_api_add_blob_image(mDocHandle, key, &aDescriptor, RangeToByteSlice(aBytes)); @@ -441,7 +441,7 @@ WebRenderAPI::AddExternalImage(ImageKey key, wr::WrExternalImageBufferType aBufferType, uint8_t aChannelIndex) { - wr_api_add_external_image(mRenderApi, + wr_api_add_external_image(mDocHandle, key, &aDescriptor, aExtID, @@ -465,7 +465,7 @@ WebRenderAPI::UpdateImageBuffer(ImageKey aKey, const ImageDescriptor& aDescriptor, Range aBytes) { - wr_api_update_image(mRenderApi, + wr_api_update_image(mDocHandle, aKey, &aDescriptor, RangeToByteSlice(aBytes)); @@ -476,7 +476,7 @@ WebRenderAPI::UpdateBlobImage(ImageKey aKey, const ImageDescriptor& aDescriptor, Range aBytes) { - wr_api_update_blob_image(mRenderApi, + wr_api_update_blob_image(mDocHandle, aKey, &aDescriptor, RangeToByteSlice(aBytes)); @@ -489,7 +489,7 @@ WebRenderAPI::UpdateExternalImage(ImageKey aKey, wr::WrExternalImageBufferType aBufferType, uint8_t aChannelIndex) { - wr_api_update_external_image(mRenderApi, + wr_api_update_external_image(mDocHandle, aKey, &aDescriptor, aExtID, @@ -500,19 +500,19 @@ WebRenderAPI::UpdateExternalImage(ImageKey aKey, void WebRenderAPI::DeleteImage(ImageKey aKey) { - wr_api_delete_image(mRenderApi, aKey); + wr_api_delete_image(mDocHandle, aKey); } void WebRenderAPI::AddRawFont(wr::FontKey aKey, Range aBytes, uint32_t aIndex) { - wr_api_add_raw_font(mRenderApi, aKey, &aBytes[0], aBytes.length(), aIndex); + wr_api_add_raw_font(mDocHandle, aKey, &aBytes[0], aBytes.length(), aIndex); } void WebRenderAPI::DeleteFont(wr::FontKey aKey) { - wr_api_delete_font(mRenderApi, aKey); + wr_api_delete_font(mDocHandle, aKey); } class EnableProfiler : public RendererEvent @@ -585,7 +585,7 @@ void WebRenderAPI::RunOnRenderThread(UniquePtr aEvent) { auto event = reinterpret_cast(aEvent.release()); - wr_api_send_external_event(mRenderApi, event); + wr_api_send_external_event(mDocHandle, event); } DisplayListBuilder::DisplayListBuilder(PipelineId aId, diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index ceeb31f3d3c1..da0906345ba7 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -126,8 +126,8 @@ public: layers::SyncHandle GetSyncHandle() const { return mSyncHandle; } protected: - WebRenderAPI(wr::RenderApi* aRawApi, wr::WindowId aId, GLint aMaxTextureSize, bool aUseANGLE, layers::SyncHandle aSyncHandle) - : mRenderApi(aRawApi) + WebRenderAPI(wr::DocumentHandle* aHandle, wr::WindowId aId, GLint aMaxTextureSize, bool aUseANGLE, layers::SyncHandle aSyncHandle) + : mDocHandle(aHandle) , mId(aId) , mMaxTextureSize(aMaxTextureSize) , mUseANGLE(aUseANGLE) @@ -138,7 +138,7 @@ protected: // Should be used only for shutdown handling void WaitFlushed(); - wr::RenderApi* mRenderApi; + wr::DocumentHandle* mDocHandle; wr::WindowId mId; GLint mMaxTextureSize; bool mUseANGLE; diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 963e28e3641a..b25240252bc6 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -56,6 +56,21 @@ fn make_slice_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] { } } +pub struct DocumentHandle { + api: RenderApi, + document_id: DocumentId, +} + +impl DocumentHandle { + pub fn new(api: RenderApi, size: DeviceUintSize) -> DocumentHandle { + let doc = api.add_document(size); + DocumentHandle { + api: api, + document_id: doc + } + } +} + #[repr(C)] pub struct WrVecU8 { data: *mut u8, @@ -531,7 +546,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, gl_context: *mut c_void, thread_pool: *mut WrThreadPool, enable_profiler: bool, - out_api: &mut *mut RenderApi, + out_handle: &mut *mut DocumentHandle, out_renderer: &mut *mut Renderer) -> bool { assert!(unsafe { is_in_render_thread() }); @@ -571,8 +586,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, ..Default::default() }; - let window_size = DeviceUintSize::new(window_width, window_height); - let (renderer, sender) = match Renderer::new(gl, opts, window_size) { + let (renderer, sender) = match Renderer::new(gl, opts) { Ok((renderer, sender)) => (renderer, sender), Err(e) => { println!(" Failed to create a Renderer: {:?}", e); @@ -588,7 +602,9 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, window_id: window_id, })); - *out_api = Box::into_raw(Box::new(sender.create_api())); + let window_size = DeviceUintSize::new(window_width, window_height); + *out_handle = Box::into_raw(Box::new( + DocumentHandle::new(sender.create_api(), window_size))); *out_renderer = Box::into_raw(Box::new(renderer)); return true; @@ -596,69 +612,70 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC #[no_mangle] -pub unsafe extern "C" fn wr_api_delete(api: *mut RenderApi) { - let api = Box::from_raw(api); - api.shut_down(); +pub unsafe extern "C" fn wr_api_delete(dh: *mut DocumentHandle) { + let handle = Box::from_raw(dh); + handle.api.delete_document(handle.document_id); + handle.api.shut_down(); } #[no_mangle] -pub extern "C" fn wr_api_add_image(api: &mut RenderApi, +pub extern "C" fn wr_api_add_image(dh: &mut DocumentHandle, image_key: WrImageKey, descriptor: &WrImageDescriptor, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - api.add_image(image_key, - descriptor.into(), - ImageData::new(copied_bytes), - None); + dh.api.add_image(image_key, + descriptor.into(), + ImageData::new(copied_bytes), + None); } #[no_mangle] -pub extern "C" fn wr_api_add_blob_image(api: &mut RenderApi, +pub extern "C" fn wr_api_add_blob_image(dh: &mut DocumentHandle, image_key: WrImageKey, descriptor: &WrImageDescriptor, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - api.add_image(image_key, - descriptor.into(), - ImageData::new_blob_image(copied_bytes), - None); + dh.api.add_image(image_key, + descriptor.into(), + ImageData::new_blob_image(copied_bytes), + None); } #[no_mangle] -pub extern "C" fn wr_api_add_external_image(api: &mut RenderApi, +pub extern "C" fn wr_api_add_external_image(dh: &mut DocumentHandle, image_key: WrImageKey, descriptor: &WrImageDescriptor, external_image_id: WrExternalImageId, buffer_type: WrExternalImageBufferType, channel_index: u8) { assert!(unsafe { is_in_compositor_thread() }); - api.add_image(image_key, - descriptor.into(), - ImageData::External(ExternalImageData { - id: external_image_id.into(), - channel_index: channel_index, - image_type: buffer_type, - }), - None); + dh.api.add_image(image_key, + descriptor.into(), + ImageData::External(ExternalImageData { + id: external_image_id.into(), + channel_index: channel_index, + image_type: buffer_type, + }), + None); } #[no_mangle] -pub extern "C" fn wr_api_update_image(api: &mut RenderApi, +pub extern "C" fn wr_api_update_image(dh: &mut DocumentHandle, key: WrImageKey, descriptor: &WrImageDescriptor, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - api.update_image(key, descriptor.into(), ImageData::new(copied_bytes), None); + dh.api.update_image(key, descriptor.into(), ImageData::new(copied_bytes), None); } #[no_mangle] pub extern "C" fn wr_api_update_external_image( - api: &mut RenderApi, + dh: &mut DocumentHandle, key: WrImageKey, descriptor: &WrImageDescriptor, external_image_id: WrExternalImageId, @@ -675,47 +692,49 @@ pub extern "C" fn wr_api_update_external_image( } ); - api.update_image(key, descriptor.into(), data, None); + dh.api.update_image(key, descriptor.into(), data, None); } #[no_mangle] -pub extern "C" fn wr_api_update_blob_image(api: &mut RenderApi, +pub extern "C" fn wr_api_update_blob_image(dh: &mut DocumentHandle, image_key: WrImageKey, descriptor: &WrImageDescriptor, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - api.update_image( - image_key, - descriptor.into(), - ImageData::new_blob_image(copied_bytes), - None + dh.api.update_image( + image_key, + descriptor.into(), + ImageData::new_blob_image(copied_bytes), + None ); } #[no_mangle] -pub extern "C" fn wr_api_delete_image(api: &mut RenderApi, +pub extern "C" fn wr_api_delete_image(dh: &mut DocumentHandle, key: WrImageKey) { assert!(unsafe { is_in_compositor_thread() }); - api.delete_image(key) + dh.api.delete_image(key) } #[no_mangle] -pub extern "C" fn wr_api_set_root_pipeline(api: &mut RenderApi, +pub extern "C" fn wr_api_set_root_pipeline(dh: &mut DocumentHandle, pipeline_id: WrPipelineId) { - api.set_root_pipeline(pipeline_id); + dh.api.set_root_pipeline(dh.document_id, pipeline_id); } #[no_mangle] -pub extern "C" fn wr_api_set_window_parameters(api: &mut RenderApi, +pub extern "C" fn wr_api_set_window_parameters(dh: &mut DocumentHandle, width: i32, height: i32) { let size = DeviceUintSize::new(width as u32, height as u32); - api.set_window_parameters(size, DeviceUintRect::new(DeviceUintPoint::new(0, 0), size)); + dh.api.set_window_parameters(dh.document_id, + size, + DeviceUintRect::new(DeviceUintPoint::new(0, 0), size)); } #[no_mangle] -pub unsafe extern "C" fn wr_api_set_root_display_list(api: &mut RenderApi, +pub unsafe extern "C" fn wr_api_set_root_display_list(dh: &mut DocumentHandle, color: ColorF, epoch: WrEpoch, viewport_width: f32, @@ -741,34 +760,36 @@ pub unsafe extern "C" fn wr_api_set_root_display_list(api: &mut RenderApi, dl_vec.extend_from_slice(dl_slice); let dl = BuiltDisplayList::from_data(dl_vec, dl_descriptor); - api.set_display_list(color, - epoch, - LayoutSize::new(viewport_width, viewport_height), - (pipeline_id, content_size.into(), dl), - preserve_frame_state); + dh.api.set_display_list(dh.document_id, + epoch, + color, + LayoutSize::new(viewport_width, viewport_height), + (pipeline_id, content_size.into(), dl), + preserve_frame_state); } #[no_mangle] -pub unsafe extern "C" fn wr_api_clear_root_display_list(api: &mut RenderApi, +pub unsafe extern "C" fn wr_api_clear_root_display_list(dh: &mut DocumentHandle, epoch: WrEpoch, pipeline_id: WrPipelineId) { let preserve_frame_state = true; let frame_builder = WebRenderFrameBuilder::new(pipeline_id, LayoutSize::zero()); - api.set_display_list(None, - epoch, - LayoutSize::new(0.0, 0.0), - frame_builder.dl_builder.finalize(), - preserve_frame_state); + dh.api.set_display_list(dh.document_id, + epoch, + None, + LayoutSize::new(0.0, 0.0), + frame_builder.dl_builder.finalize(), + preserve_frame_state); } #[no_mangle] -pub extern "C" fn wr_api_generate_frame(api: &mut RenderApi) { - api.generate_frame(None); +pub extern "C" fn wr_api_generate_frame(dh: &mut DocumentHandle) { + dh.api.generate_frame(dh.document_id, None); } #[no_mangle] -pub extern "C" fn wr_api_generate_frame_with_properties(api: &mut RenderApi, +pub extern "C" fn wr_api_generate_frame_with_properties(dh: &mut DocumentHandle, opacity_array: *const WrOpacityProperty, opacity_count: usize, transform_array: *const WrTransformProperty, @@ -803,20 +824,20 @@ pub extern "C" fn wr_api_generate_frame_with_properties(api: &mut RenderApi, } } - api.generate_frame(Some(properties)); + dh.api.generate_frame(dh.document_id, Some(properties)); } /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC #[no_mangle] -pub extern "C" fn wr_api_send_external_event(api: &mut RenderApi, +pub extern "C" fn wr_api_send_external_event(dh: &mut DocumentHandle, evt: usize) { assert!(unsafe { !is_in_render_thread() }); - api.send_external_event(ExternalEvent::from_raw(evt)); + dh.api.send_external_event(ExternalEvent::from_raw(evt)); } #[no_mangle] -pub extern "C" fn wr_api_add_raw_font(api: &mut RenderApi, +pub extern "C" fn wr_api_add_raw_font(dh: &mut DocumentHandle, key: WrFontKey, font_buffer: *mut u8, buffer_size: usize, @@ -827,19 +848,19 @@ pub extern "C" fn wr_api_add_raw_font(api: &mut RenderApi, let mut font_vector = Vec::new(); font_vector.extend_from_slice(font_slice); - api.add_raw_font(key, font_vector, index); + dh.api.add_raw_font(key, font_vector, index); } #[no_mangle] -pub extern "C" fn wr_api_delete_font(api: &mut RenderApi, +pub extern "C" fn wr_api_delete_font(dh: &mut DocumentHandle, key: WrFontKey) { assert!(unsafe { is_in_compositor_thread() }); - api.delete_font(key); + dh.api.delete_font(key); } #[no_mangle] -pub unsafe extern "C" fn wr_api_get_namespace(api: &mut RenderApi) -> WrIdNamespace { - api.id_namespace +pub unsafe extern "C" fn wr_api_get_namespace(dh: &mut DocumentHandle) -> WrIdNamespace { + dh.document_id.0 } // RenderThread WIP notes: @@ -1050,13 +1071,13 @@ pub extern "C" fn wr_dp_pop_scroll_layer(state: &mut WrState) { } #[no_mangle] -pub extern "C" fn wr_scroll_layer_with_id(api: &mut RenderApi, +pub extern "C" fn wr_scroll_layer_with_id(dh: &mut DocumentHandle, pipeline_id: WrPipelineId, scroll_id: u64, new_scroll_origin: LayoutPoint) { assert!(unsafe { is_in_compositor_thread() }); let clip_id = ClipId::new(scroll_id, pipeline_id); - api.scroll_node_with_id(new_scroll_origin.into(), clip_id, ScrollClamping::NoClamping); + dh.api.scroll_node_with_id(dh.document_id, new_scroll_origin.into(), clip_id, ScrollClamping::NoClamping); } #[no_mangle] From 8487cf859b855a4c8e0aed723f00d19d3f6cd01e Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Mon, 31 Jul 2017 14:21:18 -0400 Subject: [PATCH 032/166] Bug 1385003 - Drop the hacky gecko IdNamespace allocator and use the IdNamespace from WR to avoid mismatches. r=sotaro MozReview-Commit-ID: 410h1ZkWBGL --HG-- extra : rebase_source : c9172918eee2dbe290b09b3753e52f6998aa9173 --- gfx/layers/ipc/CompositorBridgeParent.cpp | 4 ++-- gfx/layers/wr/WebRenderBridgeParent.cpp | 8 +++----- gfx/layers/wr/WebRenderBridgeParent.h | 6 ------ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index db3d032c9ee4..03966ad926d1 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1695,8 +1695,6 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel RefPtr widget = mWidget; RefPtr api = wr::WebRenderAPI::Create( gfxPrefs::WebRenderProfilerEnabled(), this, Move(widget), aSize); - RefPtr asyncMgr = - new AsyncImagePipelineManager(WebRenderBridgeParent::AllocIdNameSpace()); if (!api) { mWrBridge = WebRenderBridgeParent::CreateDestroyed(); mWrBridge.get()->AddRef(); // IPDL reference @@ -1704,6 +1702,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE); return mWrBridge; } + RefPtr asyncMgr = + new AsyncImagePipelineManager(api->GetNamespace()); api->SetRootPipeline(aPipelineId); RefPtr animStorage = GetAnimationStorage(); mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, Move(api), Move(asyncMgr), Move(animStorage)); diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index a96fe0f2d4e1..653b69acfa52 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -112,8 +112,6 @@ private: InfallibleTArray* mActorsToDestroy; }; -/* static */ uint32_t WebRenderBridgeParent::sIdNameSpace = 0; - WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompositorBridge, const wr::PipelineId& aPipelineId, widget::CompositorWidget* aWidget, @@ -131,7 +129,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos , mChildLayerObserverEpoch(0) , mParentLayerObserverEpoch(0) , mWrEpoch(0) - , mIdNamespace(AllocIdNameSpace()) + , mIdNamespace(aApi->GetNamespace()) , mPaused(false) , mDestroyed(false) , mForceRendering(false) @@ -150,7 +148,7 @@ WebRenderBridgeParent::WebRenderBridgeParent() , mChildLayerObserverEpoch(0) , mParentLayerObserverEpoch(0) , mWrEpoch(0) - , mIdNamespace(AllocIdNameSpace()) + , mIdNamespace{0} , mPaused(false) , mDestroyed(true) , mForceRendering(false) @@ -886,7 +884,7 @@ WebRenderBridgeParent::UpdateWebRender(CompositorVsyncScheduler* aScheduler, // Update id name space to identify obsoleted keys. // Since usage of invalid keys could cause crash in webrender. - mIdNamespace = AllocIdNameSpace(); + mIdNamespace = aApi->GetNamespace(); // XXX Remove it when webrender supports sharing/moving Keys between different webrender instances. // XXX It requests client to update/reallocate webrender related resources, // but parent side does not wait end of the update. diff --git a/gfx/layers/wr/WebRenderBridgeParent.h b/gfx/layers/wr/WebRenderBridgeParent.h index baddf3e3ea11..4842ab59d3df 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.h +++ b/gfx/layers/wr/WebRenderBridgeParent.h @@ -187,10 +187,6 @@ public: void UpdateAPZ(); const WebRenderScrollData& GetScrollData() const; - static wr::IdNamespace AllocIdNameSpace() { - return wr::IdNamespace { ++sIdNameSpace }; - } - void FlushRendering(bool aIsSync); void ScheduleComposition(); @@ -296,8 +292,6 @@ private: // Can only be accessed on the compositor thread. WebRenderScrollData mScrollData; - - static uint32_t sIdNameSpace; }; } // namespace layers From 162dcae649c994bce091edced1aec218d70cbc34 Mon Sep 17 00:00:00 2001 From: sotaro Date: Wed, 9 Aug 2017 08:46:25 -0400 Subject: [PATCH 033/166] Bug 1385003 - Use a different WebRenderAPI instance for each WebRenderBridgeParent. r=kats Previously, the WebRenderBridgeParent for each content layer tree would use the same WebRenderAPI instance as the top-level WebRenderBridgeParent for that window. However, in order to make the namespacing changes work we now need to use a separate WebRenderAPI instance for each WebRenderBridgeParent. The content WebRenderAPIs are cloned from the parent one, so that they all share the same backend, but can allocate resource IDs in distinct namespaces. MozReview-Commit-ID: 7VTFL8F09n7 --HG-- extra : rebase_source : 2da1d03abc23bd7852e4b12fe133889bd80cad53 --- gfx/layers/ipc/CompositorBridgeParent.cpp | 14 ++++--- gfx/layers/ipc/CompositorBridgeParent.h | 2 + .../CrossProcessCompositorBridgeParent.cpp | 2 +- gfx/layers/wr/AsyncImagePipelineManager.cpp | 42 ++++++++++--------- gfx/layers/wr/AsyncImagePipelineManager.h | 17 ++++---- gfx/layers/wr/WebRenderBridgeParent.cpp | 10 +++-- gfx/webrender_bindings/WebRenderAPI.cpp | 21 ++++++++-- gfx/webrender_bindings/WebRenderAPI.h | 3 ++ gfx/webrender_bindings/src/bindings.rs | 20 +++++++-- 9 files changed, 87 insertions(+), 44 deletions(-) diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 03966ad926d1..e593b5343856 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -463,6 +463,9 @@ CompositorBridgeParent::StopAndClearResources() }); mWrBridge->Destroy(); mWrBridge = nullptr; + mAsyncImageManager->Destroy(); + // WebRenderAPI should be already destructed + mAsyncImageManager = nullptr; } if (mCompositor) { @@ -1654,8 +1657,9 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child) ScheduleComposition(); } if (mWrBridge && sIndirectLayerTrees[child].mWrBridge) { + RefPtr api = mWrBridge->GetWebRenderAPI()->Clone(); sIndirectLayerTrees[child].mWrBridge->UpdateWebRender(mWrBridge->CompositorScheduler(), - mWrBridge->GetWebRenderAPI(), + api, mWrBridge->AsyncImageManager(), GetAnimationStorage()); // Pretend we composited, since parent CompositorBridgeParent was replaced. @@ -1702,8 +1706,8 @@ CompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipel *aTextureFactoryIdentifier = TextureFactoryIdentifier(LayersBackend::LAYERS_NONE); return mWrBridge; } - RefPtr asyncMgr = - new AsyncImagePipelineManager(api->GetNamespace()); + mAsyncImageManager = new AsyncImagePipelineManager(api->Clone()); + RefPtr asyncMgr = mAsyncImageManager; api->SetRootPipeline(aPipelineId); RefPtr animStorage = GetAnimationStorage(); mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr, Move(api), Move(asyncMgr), Move(animStorage)); @@ -1953,10 +1957,10 @@ CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart, void CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) { - if (!mWrBridge) { + if (!mWrBridge || !mAsyncImageManager) { return; } - mWrBridge->AsyncImageManager()->Update(aPipelineId, aEpoch); + mAsyncImageManager->Update(aPipelineId, aEpoch); if (mPaused) { return; diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h index 5dcf39b3d1a7..70940cded66e 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.h +++ b/gfx/layers/ipc/CompositorBridgeParent.h @@ -65,6 +65,7 @@ namespace layers { class APZCTreeManager; class APZCTreeManagerParent; class AsyncCompositionManager; +class AsyncImagePipelineManager; class Compositor; class CompositorAnimationStorage; class CompositorBridgeParent; @@ -580,6 +581,7 @@ protected: RefPtr mLayerManager; RefPtr mCompositor; RefPtr mCompositionManager; + RefPtr mAsyncImageManager; RefPtr mWrBridge; widget::CompositorWidget* mWidget; TimeStamp mTestTime; diff --git a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp index 33b9f9a75aef..04be18ba4aad 100644 --- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp @@ -225,7 +225,7 @@ CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::Pipeli } WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get(); - RefPtr api = root->GetWebRenderAPI(); + RefPtr api = root->GetWebRenderAPI()->Clone(); RefPtr holder = root->AsyncImageManager(); RefPtr animStorage = cbp->GetAnimationStorage(); parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder), Move(animStorage)); diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index 45bb46314a36..4ac2169a664f 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -23,8 +23,9 @@ AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline() , mMixBlendMode(wr::MixBlendMode::Normal) {} -AsyncImagePipelineManager::AsyncImagePipelineManager(wr::IdNamespace aIdNamespace) - : mIdNamespace(aIdNamespace) +AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed&& aApi) + : mApi(aApi) + , mIdNamespace(mApi->GetNamespace()) , mResourceId(0) , mAsyncImageEpoch(0) , mDestroyed(false) @@ -38,9 +39,11 @@ AsyncImagePipelineManager::~AsyncImagePipelineManager() } void -AsyncImagePipelineManager::Destroy(wr::WebRenderAPI* aApi) +AsyncImagePipelineManager::Destroy() { - DeleteOldAsyncImages(aApi); + MOZ_ASSERT(!mDestroyed); + DeleteOldAsyncImages(); + mApi = nullptr; mDestroyed = true; } @@ -51,10 +54,11 @@ AsyncImagePipelineManager::HasKeysToDelete() } void -AsyncImagePipelineManager::DeleteOldAsyncImages(wr::WebRenderAPI* aApi) +AsyncImagePipelineManager::DeleteOldAsyncImages() { + MOZ_ASSERT(!mDestroyed); for (wr::ImageKey key : mKeysToDelete) { - aApi->DeleteImage(key); + mApi->DeleteImage(key); } mKeysToDelete.Clear(); } @@ -111,7 +115,7 @@ AsyncImagePipelineManager::AddAsyncImagePipeline(const wr::PipelineId& aPipeline } void -AsyncImagePipelineManager::RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, const wr::PipelineId& aPipelineId) +AsyncImagePipelineManager::RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId) { if (mDestroyed) { return; @@ -121,9 +125,9 @@ AsyncImagePipelineManager::RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, cons if (auto entry = mAsyncImagePipelines.Lookup(id)) { AsyncImagePipeline* holder = entry.Data(); ++mAsyncImageEpoch; // Update webrender epoch - aApi->ClearRootDisplayList(wr::NewEpoch(mAsyncImageEpoch), aPipelineId); + mApi->ClearRootDisplayList(wr::NewEpoch(mAsyncImageEpoch), aPipelineId); for (wr::ImageKey key : holder->mKeys) { - aApi->DeleteImage(key); + mApi->DeleteImage(key); } entry.Remove(); RemovePipeline(aPipelineId, wr::NewEpoch(mAsyncImageEpoch)); @@ -155,7 +159,7 @@ AsyncImagePipelineManager::UpdateAsyncImagePipeline(const wr::PipelineId& aPipel } bool -AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray& aKeys) +AsyncImagePipelineManager::GenerateImageKeyForTextureHost(TextureHost* aTexture, nsTArray& aKeys) { MOZ_ASSERT(aKeys.IsEmpty()); MOZ_ASSERT(aTexture); @@ -166,7 +170,7 @@ AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi wrTexture->GetWRImageKeys(aKeys, std::bind(&AsyncImagePipelineManager::GenerateImageKey, this)); MOZ_ASSERT(!aKeys.IsEmpty()); Range keys(&aKeys[0], aKeys.Length()); - wrTexture->AddWRImage(aApi, keys, wrTexture->GetExternalImageKey()); + wrTexture->AddWRImage(mApi, keys, wrTexture->GetExternalImageKey()); return true; } else { RefPtr dSurf = aTexture->GetAsSurface(); @@ -185,15 +189,14 @@ AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi wr::ImageKey key = GenerateImageKey(); aKeys.AppendElement(key); - aApi->AddImage(key, descriptor, slice); + mApi->AddImage(key, descriptor, slice); dSurf->Unmap(); } return false; } bool -AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi, - bool& aUseExternalImage, +AsyncImagePipelineManager::UpdateImageKeys(bool& aUseExternalImage, AsyncImagePipeline* aImageMgr, nsTArray& aKeys, nsTArray& aKeysToDelete) @@ -231,7 +234,7 @@ AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi, return true; } - aUseExternalImage = aImageMgr->mUseExternalImage = GenerateImageKeyForTextureHost(aApi, texture, aKeys); + aUseExternalImage = aImageMgr->mUseExternalImage = GenerateImageKeyForTextureHost(texture, aKeys); MOZ_ASSERT(!aKeys.IsEmpty()); aImageMgr->mKeys.AppendElements(aKeys); aImageMgr->mCurrentTexture = texture; @@ -239,7 +242,7 @@ AsyncImagePipelineManager::UpdateImageKeys(wr::WebRenderAPI* aApi, } void -AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi) +AsyncImagePipelineManager::ApplyAsyncImages() { if (mDestroyed || mAsyncImagePipelines.Count() == 0) { return; @@ -255,8 +258,7 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi) nsTArray keys; bool useExternalImage = false; - bool updateDisplayList = UpdateImageKeys(aApi, - useExternalImage, + bool updateDisplayList = UpdateImageKeys(useExternalImage, pipeline, keys, keysToDelete); @@ -306,11 +308,11 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::WebRenderAPI* aApi) wr::BuiltDisplayList dl; wr::LayoutSize builderContentSize; builder.Finalize(builderContentSize, dl); - aApi->SetRootDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.width, pipeline->mScBounds.height), + mApi->SetRootDisplayList(gfx::Color(0.f, 0.f, 0.f, 0.f), epoch, LayerSize(pipeline->mScBounds.width, pipeline->mScBounds.height), pipelineId, builderContentSize, dl.dl_desc, dl.dl.inner.data, dl.dl.inner.length); } - DeleteOldAsyncImages(aApi); + DeleteOldAsyncImages(); mKeysToDelete.SwapElements(keysToDelete); } diff --git a/gfx/layers/wr/AsyncImagePipelineManager.h b/gfx/layers/wr/AsyncImagePipelineManager.h index c2acb1f3f759..354e9b548a20 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.h +++ b/gfx/layers/wr/AsyncImagePipelineManager.h @@ -12,6 +12,7 @@ #include "mozilla/gfx/Point.h" #include "mozilla/layers/TextureHost.h" #include "mozilla/Maybe.h" +#include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/webrender/WebRenderTypes.h" #include "nsClassHashtable.h" @@ -34,13 +35,13 @@ class AsyncImagePipelineManager final public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager) - explicit AsyncImagePipelineManager(wr::IdNamespace aIdNamespace); + explicit AsyncImagePipelineManager(already_AddRefed&& aApi); protected: ~AsyncImagePipelineManager(); public: - void Destroy(wr::WebRenderAPI* aApi); + void Destroy(); bool HasKeysToDelete(); void AddPipeline(const wr::PipelineId& aPipelineId); @@ -70,7 +71,7 @@ public: } void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId, WebRenderImageHost* aImageHost); - void RemoveAsyncImagePipeline(wr::WebRenderAPI* aApi, const wr::PipelineId& aPipelineId); + void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId); void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId, const LayerRect& aScBounds, @@ -78,7 +79,7 @@ public: const gfx::MaybeIntSize& aScaleToSize, const wr::ImageRendering& aFilter, const wr::MixBlendMode& aMixBlendMode); - void ApplyAsyncImages(wr::WebRenderAPI* aApi); + void ApplyAsyncImages(); void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification) { @@ -91,7 +92,7 @@ public: } private: - void DeleteOldAsyncImages(wr::WebRenderAPI* aApi); + void DeleteOldAsyncImages(); uint32_t GetNextResourceId() { return ++mResourceId; } wr::IdNamespace GetNamespace() { return mIdNamespace; } @@ -102,7 +103,7 @@ private: key.mHandle = GetNextResourceId(); return key; } - bool GenerateImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray& aKeys); + bool GenerateImageKeyForTextureHost(TextureHost* aTexture, nsTArray& aKeys); struct ForwardingTextureHost { ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture) @@ -135,12 +136,12 @@ private: nsTArray mKeys; }; - bool UpdateImageKeys(wr::WebRenderAPI* aApi, - bool& aUseExternalImage, + bool UpdateImageKeys(bool& aUseExternalImage, AsyncImagePipeline* aImageMgr, nsTArray& aKeys, nsTArray& aKeysToDelete); + RefPtr mApi; wr::IdNamespace mIdNamespace; uint32_t mResourceId; diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 653b69acfa52..a139c17443a1 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -792,7 +792,7 @@ WebRenderBridgeParent::RecvRemovePipelineIdForCompositable(const wr::PipelineId& } wrHost->ClearWrBridge(); - mAsyncImageManager->RemoveAsyncImagePipeline(mApi, aPipelineId); + mAsyncImageManager->RemoveAsyncImagePipeline(aPipelineId); mAsyncCompositables.Remove(wr::AsUint64(aPipelineId)); return IPC_OK(); } @@ -1116,7 +1116,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In nsTArray transformArray; mAsyncImageManager->SetCompositionTime(TimeStamp::Now()); - mAsyncImageManager->ApplyAsyncImages(mApi); + mAsyncImageManager->ApplyAsyncImages(); SampleAnimations(opacityArray, transformArray); if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) { @@ -1313,7 +1313,7 @@ WebRenderBridgeParent::ClearResources() wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key()); RefPtr host = iter.Data(); host->ClearWrBridge(); - mAsyncImageManager->RemoveAsyncImagePipeline(mApi, pipelineId); + mAsyncImageManager->RemoveAsyncImagePipeline(pipelineId); } mAsyncCompositables.Clear(); @@ -1329,6 +1329,7 @@ WebRenderBridgeParent::ClearResources() } mAnimStorage = nullptr; mCompositorScheduler = nullptr; + mAsyncImageManager = nullptr; mApi = nullptr; mCompositorBridge = nullptr; } @@ -1452,6 +1453,9 @@ void WebRenderBridgeParent::ExtractImageCompositeNotifications(nsTArray* aNotifications) { MOZ_ASSERT(mWidget); + if (mDestroyed) { + return; + } mAsyncImageManager->FlushImageNotifications(aNotifications); } diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 39b866648a08..9ad06ca4e9c1 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -176,6 +176,17 @@ WebRenderAPI::Create(bool aEnableProfiler, return RefPtr(new WebRenderAPI(docHandle, id, maxTextureSize, useANGLE, syncHandle)).forget(); } +already_AddRefed +WebRenderAPI::Clone() +{ + wr::DocumentHandle* docHandle = nullptr; + wr_api_clone(mDocHandle, &docHandle); + + RefPtr renderApi = new WebRenderAPI(docHandle, mId, mMaxTextureSize, mUseANGLE, mSyncHandle); + renderApi->mRootApi = this; // Hold root api + return renderApi.forget(); +} + wr::WrIdNamespace WebRenderAPI::GetNamespace() { return wr_api_get_namespace(mDocHandle); @@ -183,10 +194,12 @@ WebRenderAPI::GetNamespace() { WebRenderAPI::~WebRenderAPI() { - layers::SynchronousTask task("Destroy WebRenderAPI"); - auto event = MakeUnique(&task); - RunOnRenderThread(Move(event)); - task.Wait(); + if (!mRootApi) { + layers::SynchronousTask task("Destroy WebRenderAPI"); + auto event = MakeUnique(&task); + RunOnRenderThread(Move(event)); + task.Wait(); + } wr_api_delete(mDocHandle); } diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index da0906345ba7..c44c31f3af43 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -47,6 +47,8 @@ public: RefPtr&& aWidget, LayoutDeviceIntSize aSize); + already_AddRefed Clone(); + wr::WindowId GetId() const { return mId; } void UpdateScrollPosition(const wr::WrPipelineId& aPipelineId, @@ -143,6 +145,7 @@ protected: GLint mMaxTextureSize; bool mUseANGLE; layers::SyncHandle mSyncHandle; + RefPtr mRootApi; friend class DisplayListBuilder; friend class layers::WebRenderBridgeParent; diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index b25240252bc6..c676c5e6bd84 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -610,12 +610,26 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, return true; } +#[no_mangle] +pub extern "C" fn wr_api_clone(dh: &mut DocumentHandle, + out_handle: &mut *mut DocumentHandle) { + assert!(unsafe { is_in_compositor_thread() }); + + let handle = DocumentHandle { + api: dh.api.clone_sender().create_api(), + document_id: dh.document_id, + }; + *out_handle = Box::into_raw(Box::new(handle)); +} + /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC #[no_mangle] pub unsafe extern "C" fn wr_api_delete(dh: *mut DocumentHandle) { let handle = Box::from_raw(dh); - handle.api.delete_document(handle.document_id); - handle.api.shut_down(); + if handle.document_id.0 == handle.api.get_namespace_id() { + handle.api.delete_document(handle.document_id); + handle.api.shut_down(); + } } #[no_mangle] @@ -860,7 +874,7 @@ pub extern "C" fn wr_api_delete_font(dh: &mut DocumentHandle, #[no_mangle] pub unsafe extern "C" fn wr_api_get_namespace(dh: &mut DocumentHandle) -> WrIdNamespace { - dh.document_id.0 + dh.api.get_namespace_id() } // RenderThread WIP notes: From bdee759275a7e1821344f6a097679e339b972a4b Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:25 -0400 Subject: [PATCH 034/166] Bug 1385003 - Autogenerated changes to go with webrender update. r=jrmuizel This regenerates the cargo lockfiles and FFI bindings header. It also revendors the third_party/rust libraries. MozReview-Commit-ID: ID0YhoIH6cz --HG-- extra : rebase_source : 7c22828a831eafcf527f2c3baf8d4d012db8f9a4 --- .../webrender_ffi_generated.h | 91 +- .../rust/freetype/.cargo-checksum.json | 2 +- third_party/rust/freetype/Cargo.toml | 40 +- third_party/rust/freetype/etc/bindgen.sh | 1 - third_party/rust/freetype/etc/bindings.h | 1 + third_party/rust/freetype/src/freetype.rs | 1698 +++++++++++++---- third_party/rust/fxhash/.cargo-checksum.json | 1 + .../rust/{heapsize-0.3.8 => fxhash}/.cargo-ok | 0 third_party/rust/fxhash/Cargo.toml | 38 + third_party/rust/fxhash/README.md | 62 + third_party/rust/fxhash/bench.rs | 78 + third_party/rust/fxhash/lib.rs | 324 ++++ .../rust/heapsize-0.3.8/.cargo-checksum.json | 1 - third_party/rust/heapsize-0.3.8/.travis.yml | 19 - third_party/rust/heapsize-0.3.8/Cargo.toml | 14 - third_party/rust/heapsize-0.3.8/README.md | 5 - third_party/rust/heapsize-0.3.8/appveyor.yml | 23 - third_party/rust/heapsize-0.3.8/build.rs | 37 - third_party/rust/heapsize-0.3.8/src/lib.rs | 323 ---- .../rust/heapsize-0.3.8/tests/tests.rs | 171 -- toolkit/library/gtest/rust/Cargo.lock | 29 +- toolkit/library/rust/Cargo.lock | 29 +- 22 files changed, 1965 insertions(+), 1022 deletions(-) create mode 100644 third_party/rust/fxhash/.cargo-checksum.json rename third_party/rust/{heapsize-0.3.8 => fxhash}/.cargo-ok (100%) create mode 100644 third_party/rust/fxhash/Cargo.toml create mode 100644 third_party/rust/fxhash/README.md create mode 100644 third_party/rust/fxhash/bench.rs create mode 100644 third_party/rust/fxhash/lib.rs delete mode 100644 third_party/rust/heapsize-0.3.8/.cargo-checksum.json delete mode 100644 third_party/rust/heapsize-0.3.8/.travis.yml delete mode 100644 third_party/rust/heapsize-0.3.8/Cargo.toml delete mode 100644 third_party/rust/heapsize-0.3.8/README.md delete mode 100644 third_party/rust/heapsize-0.3.8/appveyor.yml delete mode 100644 third_party/rust/heapsize-0.3.8/build.rs delete mode 100644 third_party/rust/heapsize-0.3.8/src/lib.rs delete mode 100644 third_party/rust/heapsize-0.3.8/tests/tests.rs diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index adaab3214a24..b3a81bc48b6a 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -2,7 +2,7 @@ * 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/. */ -/* Generated with cbindgen:0.1.19 */ +/* Generated with cbindgen:0.1.20 */ /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. * To generate this file: @@ -144,9 +144,9 @@ enum class YuvColorSpace : uint32_t { struct Arc_VecU8; -struct LayerPixel; +struct DocumentHandle; -struct RenderApi; +struct LayerPixel; struct Renderer; @@ -255,8 +255,10 @@ struct Epoch { typedef Epoch WrEpoch; +typedef uint32_t PipelineSourceId; + struct PipelineId { - uint32_t mNamespace; + PipelineSourceId mNamespace; uint32_t mHandle; bool operator==(const PipelineId& aOther) const { @@ -285,11 +287,13 @@ struct BuiltDisplayListDescriptor { uint64_t builder_start_time; uint64_t builder_finish_time; uint64_t send_start_time; + size_t glyph_offset; bool operator==(const BuiltDisplayListDescriptor& aOther) const { return builder_start_time == aOther.builder_start_time && builder_finish_time == aOther.builder_finish_time && - send_start_time == aOther.send_start_time; + send_start_time == aOther.send_start_time && + glyph_offset == aOther.glyph_offset; } }; @@ -454,20 +458,6 @@ struct GradientStop { } }; -struct SideOffsets2D_f32 { - float top; - float right; - float bottom; - float left; - - bool operator==(const SideOffsets2D_f32& aOther) const { - return top == aOther.top && - right == aOther.right && - bottom == aOther.bottom && - left == aOther.left; - } -}; - struct SideOffsets2D_u32 { uint32_t top; uint32_t right; @@ -482,6 +472,20 @@ struct SideOffsets2D_u32 { } }; +struct SideOffsets2D_f32 { + float top; + float right; + float bottom; + float left; + + bool operator==(const SideOffsets2D_f32& aOther) const { + return top == aOther.top && + right == aOther.right && + bottom == aOther.bottom && + left == aOther.left; + } +}; + struct NinePatchDescriptor { uint32_t width; uint32_t height; @@ -540,8 +544,10 @@ struct WrFilterOp { } }; +typedef uint32_t GlyphIndex; + struct GlyphInstance { - uint32_t index; + GlyphIndex index; LayoutPoint point; bool operator==(const GlyphInstance& aOther) const { @@ -626,14 +632,14 @@ const VecU8 *wr_add_ref_arc(const ArcVecU8 *aArc) WR_FUNC; WR_INLINE -void wr_api_add_blob_image(RenderApi *aApi, +void wr_api_add_blob_image(DocumentHandle *aDh, WrImageKey aImageKey, const WrImageDescriptor *aDescriptor, ByteSlice aBytes) WR_FUNC; WR_INLINE -void wr_api_add_external_image(RenderApi *aApi, +void wr_api_add_external_image(DocumentHandle *aDh, WrImageKey aImageKey, const WrImageDescriptor *aDescriptor, WrExternalImageId aExternalImageId, @@ -642,14 +648,14 @@ void wr_api_add_external_image(RenderApi *aApi, WR_FUNC; WR_INLINE -void wr_api_add_image(RenderApi *aApi, +void wr_api_add_image(DocumentHandle *aDh, WrImageKey aImageKey, const WrImageDescriptor *aDescriptor, ByteSlice aBytes) WR_FUNC; WR_INLINE -void wr_api_add_raw_font(RenderApi *aApi, +void wr_api_add_raw_font(DocumentHandle *aDh, WrFontKey aKey, uint8_t *aFontBuffer, size_t aBufferSize, @@ -657,22 +663,27 @@ void wr_api_add_raw_font(RenderApi *aApi, WR_FUNC; WR_INLINE -void wr_api_clear_root_display_list(RenderApi *aApi, +void wr_api_clear_root_display_list(DocumentHandle *aDh, WrEpoch aEpoch, WrPipelineId aPipelineId) WR_FUNC; WR_INLINE -void wr_api_delete(RenderApi *aApi) +void wr_api_clone(DocumentHandle *aDh, + DocumentHandle **aOutHandle) +WR_FUNC; + +WR_INLINE +void wr_api_delete(DocumentHandle *aDh) WR_DESTRUCTOR_SAFE_FUNC; WR_INLINE -void wr_api_delete_font(RenderApi *aApi, +void wr_api_delete_font(DocumentHandle *aDh, WrFontKey aKey) WR_FUNC; WR_INLINE -void wr_api_delete_image(RenderApi *aApi, +void wr_api_delete_image(DocumentHandle *aDh, WrImageKey aKey) WR_FUNC; @@ -684,11 +695,11 @@ void wr_api_finalize_builder(WrState *aState, WR_FUNC; WR_INLINE -void wr_api_generate_frame(RenderApi *aApi) +void wr_api_generate_frame(DocumentHandle *aDh) WR_FUNC; WR_INLINE -void wr_api_generate_frame_with_properties(RenderApi *aApi, +void wr_api_generate_frame_with_properties(DocumentHandle *aDh, const WrOpacityProperty *aOpacityArray, size_t aOpacityCount, const WrTransformProperty *aTransformArray, @@ -696,16 +707,16 @@ void wr_api_generate_frame_with_properties(RenderApi *aApi, WR_FUNC; WR_INLINE -WrIdNamespace wr_api_get_namespace(RenderApi *aApi) +WrIdNamespace wr_api_get_namespace(DocumentHandle *aDh) WR_FUNC; WR_INLINE -void wr_api_send_external_event(RenderApi *aApi, +void wr_api_send_external_event(DocumentHandle *aDh, size_t aEvt) WR_DESTRUCTOR_SAFE_FUNC; WR_INLINE -void wr_api_set_root_display_list(RenderApi *aApi, +void wr_api_set_root_display_list(DocumentHandle *aDh, ColorF aColor, WrEpoch aEpoch, float aViewportWidth, @@ -718,25 +729,25 @@ void wr_api_set_root_display_list(RenderApi *aApi, WR_FUNC; WR_INLINE -void wr_api_set_root_pipeline(RenderApi *aApi, +void wr_api_set_root_pipeline(DocumentHandle *aDh, WrPipelineId aPipelineId) WR_FUNC; WR_INLINE -void wr_api_set_window_parameters(RenderApi *aApi, +void wr_api_set_window_parameters(DocumentHandle *aDh, int32_t aWidth, int32_t aHeight) WR_FUNC; WR_INLINE -void wr_api_update_blob_image(RenderApi *aApi, +void wr_api_update_blob_image(DocumentHandle *aDh, WrImageKey aImageKey, const WrImageDescriptor *aDescriptor, ByteSlice aBytes) WR_FUNC; WR_INLINE -void wr_api_update_external_image(RenderApi *aApi, +void wr_api_update_external_image(DocumentHandle *aDh, WrImageKey aKey, const WrImageDescriptor *aDescriptor, WrExternalImageId aExternalImageId, @@ -745,7 +756,7 @@ void wr_api_update_external_image(RenderApi *aApi, WR_FUNC; WR_INLINE -void wr_api_update_image(RenderApi *aApi, +void wr_api_update_image(DocumentHandle *aDh, WrImageKey aKey, const WrImageDescriptor *aDescriptor, ByteSlice aBytes) @@ -1026,7 +1037,7 @@ void wr_renderer_update(Renderer *aRenderer) WR_FUNC; WR_INLINE -void wr_scroll_layer_with_id(RenderApi *aApi, +void wr_scroll_layer_with_id(DocumentHandle *aDh, WrPipelineId aPipelineId, uint64_t aScrollId, LayoutPoint aNewScrollOrigin) @@ -1060,7 +1071,7 @@ bool wr_window_new(WrWindowId aWindowId, void *aGlContext, WrThreadPool *aThreadPool, bool aEnableProfiler, - RenderApi **aOutApi, + DocumentHandle **aOutHandle, Renderer **aOutRenderer) WR_FUNC; diff --git a/third_party/rust/freetype/.cargo-checksum.json b/third_party/rust/freetype/.cargo-checksum.json index 439ac8d786c0..8ea66cdf9291 100644 --- a/third_party/rust/freetype/.cargo-checksum.json +++ b/third_party/rust/freetype/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"b66e958a27e280a79ae1742be91e02cbaf7392851d430f19b13f3619861860e2","COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"7d09decba6c94743746eb13ebd51735356ec6a1125d33da708d3e141148c81c3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","Makefile.in":"7348b5f8a577048279b3f98e2c2b5705f506cf5b4b1e6bb542cc0b1e62468411","README.md":"755e885eb12f7b0b459c8b579f20cd941e55f0197b947591131daf048c5d7bc6","configure":"e0e6ba778e5f5784fa87abf235aa4f3da750d922bfb26a34803d9674577d56ec","etc/bindgen.sh":"116938e8c7a4500e056f719c66bdc896739c8b0a34a16e6a29a9e335f7458648","etc/bindings.h":"f6110c7a692e24f9c6d1c4a78ba8a7750952b397b86a5ac466353c7c57cfb7bb","src/freetype.rs":"0e27e13cca4f79569718fa4c247b8f7020388d8a84ad5f971c376a0658073cfa","src/lib.rs":"812e79af46e33a93420c8301ad95392f5e8a57266b3e43c47085c6dd0c63653f","src/tt_os2.rs":"9517c53fc4e575ceb615d554dc72812dcbb532bf94883d51202b24caae1a1418"},"package":"fde23272c687e4570aefec06cb71174ec0f5284b725deac4e77ba2665d635faf"} \ No newline at end of file +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"b66e958a27e280a79ae1742be91e02cbaf7392851d430f19b13f3619861860e2","COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"ec1a0a3ceb37de795193e244fb3781cf87d25ea610f150976958468881da76a7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","Makefile.in":"7348b5f8a577048279b3f98e2c2b5705f506cf5b4b1e6bb542cc0b1e62468411","README.md":"755e885eb12f7b0b459c8b579f20cd941e55f0197b947591131daf048c5d7bc6","configure":"e0e6ba778e5f5784fa87abf235aa4f3da750d922bfb26a34803d9674577d56ec","etc/bindgen.sh":"39c1d5298f6e46380f0616d6080bd2c3ead5f04149bcf5b7345c56dae2000e79","etc/bindings.h":"b531980f5739536dfc1484236d436efd18f448b4ea15001d1dfbbaf381ad054f","src/freetype.rs":"445a3d48974dcf22961b612ef6cdef48c2dedc1ccc6e73a88eee53fa601859d8","src/lib.rs":"812e79af46e33a93420c8301ad95392f5e8a57266b3e43c47085c6dd0c63653f","src/tt_os2.rs":"9517c53fc4e575ceb615d554dc72812dcbb532bf94883d51202b24caae1a1418"},"package":"398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"} \ No newline at end of file diff --git a/third_party/rust/freetype/Cargo.toml b/third_party/rust/freetype/Cargo.toml index 0c4db38fe89f..23a7384f4dba 100644 --- a/third_party/rust/freetype/Cargo.toml +++ b/third_party/rust/freetype/Cargo.toml @@ -1,19 +1,33 @@ -[package] -description = "Bindings for Freetype used by Servo" -license = "Apache-2.0 / MIT" -name = "freetype" -version = "0.2.0" -authors = ["The Servo Project Developers"] -documentation = "http://doc.servo.org/freetype/" -repository = "https://github.com/servo/rust-freetype" +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) -[features] -default = ["servo-freetype-sys"] +[package] +name = "freetype" +version = "0.3.0" +authors = ["The Servo Project Developers"] +description = "Bindings for Freetype used by Servo" +documentation = "http://doc.servo.org/freetype/" +license = "Apache-2.0 / MIT" +repository = "https://github.com/servo/rust-freetype" [lib] name = "freetype" crate-type = ["rlib"] +[dependencies.servo-freetype-sys] +version = "4.0.2" +optional = true -[dependencies] -servo-freetype-sys = { version = "4.0.2", optional = true } -libc = "0.2" +[dependencies.libc] +version = "0.2" + +[features] +default = ["servo-freetype-sys"] diff --git a/third_party/rust/freetype/etc/bindgen.sh b/third_party/rust/freetype/etc/bindgen.sh index 9cce64708223..2b8b9f684d4e 100755 --- a/third_party/rust/freetype/etc/bindgen.sh +++ b/third_party/rust/freetype/etc/bindgen.sh @@ -7,7 +7,6 @@ cd "$(dirname $0)" # We blacklist FT_Error and import our own in order to have convenience methods # on it instead of being a plain integer. "${BINDGEN}" bindings.h -o ../src/freetype.rs \ - --no-unstable-rust \ --blacklist-type "FT_(Int16|UInt16|Int32|UInt32|Int16|Int64|UInt64)" \ --raw-line "pub type FT_Int16 = i16;" \ --raw-line "pub type FT_UInt16 = u16;" \ diff --git a/third_party/rust/freetype/etc/bindings.h b/third_party/rust/freetype/etc/bindings.h index 5308bbc1a2cd..34c894bf0df6 100644 --- a/third_party/rust/freetype/etc/bindings.h +++ b/third_party/rust/freetype/etc/bindings.h @@ -3,3 +3,4 @@ #include #include #include +#include diff --git a/third_party/rust/freetype/src/freetype.rs b/third_party/rust/freetype/src/freetype.rs index 232888e0c725..ccf8a2b5fa07 100644 --- a/third_party/rust/freetype/src/freetype.rs +++ b/third_party/rust/freetype/src/freetype.rs @@ -99,7 +99,6 @@ pub const FT_LOAD_LINEAR_DESIGN: ::std::os::raw::c_uint = 8192; pub const FT_LOAD_NO_AUTOHINT: ::std::os::raw::c_uint = 32768; pub const FT_LOAD_COLOR: ::std::os::raw::c_uint = 1048576; pub const FT_LOAD_COMPUTE_METRICS: ::std::os::raw::c_uint = 2097152; -pub const FT_LOAD_BITMAP_METRICS_ONLY: ::std::os::raw::c_uint = 4194304; pub const FT_LOAD_ADVANCE_ONLY: ::std::os::raw::c_uint = 256; pub const FT_LOAD_SBITS_ONLY: ::std::os::raw::c_uint = 16384; pub const FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS: ::std::os::raw::c_uint = 1; @@ -135,8 +134,30 @@ pub struct FT_MemoryRec_ { } #[test] fn bindgen_test_layout_FT_MemoryRec_() { - assert_eq!(::std::mem::size_of::() , 32usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 32usize , concat ! ( + "Size of: " , stringify ! ( FT_MemoryRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_MemoryRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_MemoryRec_ ) ) . user as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_MemoryRec_ ) , "::" + , stringify ! ( user ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_MemoryRec_ ) ) . alloc as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_MemoryRec_ ) , "::" + , stringify ! ( alloc ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_MemoryRec_ ) ) . free as * const _ as + usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_MemoryRec_ ) , "::" + , stringify ! ( free ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_MemoryRec_ ) ) . realloc as * const _ + as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_MemoryRec_ ) , "::" + , stringify ! ( realloc ) )); } impl Clone for FT_MemoryRec_ { fn clone(&self) -> Self { *self } @@ -175,8 +196,60 @@ pub struct FT_StreamRec_ { } #[test] fn bindgen_test_layout_FT_StreamRec_() { - assert_eq!(::std::mem::size_of::() , 80usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 80usize , concat ! ( + "Size of: " , stringify ! ( FT_StreamRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_StreamRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . base as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( base ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . size as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( size ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . pos as * const _ as + usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( pos ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . descriptor as * const + _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( descriptor ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . pathname as * const _ + as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( pathname ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . read as * const _ as + usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( read ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . close as * const _ as + usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( close ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . memory as * const _ + as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( memory ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . cursor as * const _ + as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( cursor ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamRec_ ) ) . limit as * const _ as + usize } , 72usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamRec_ ) , "::" + , stringify ! ( limit ) )); } impl Clone for FT_StreamRec_ { fn clone(&self) -> Self { *self } @@ -191,13 +264,25 @@ pub struct FT_StreamDesc_ { } #[test] fn bindgen_test_layout_FT_StreamDesc_() { - assert_eq!(::std::mem::size_of::() , 8usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( + "Size of: " , stringify ! ( FT_StreamDesc_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_StreamDesc_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamDesc_ ) ) . value as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamDesc_ ) , "::" + , stringify ! ( value ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_StreamDesc_ ) ) . pointer as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_StreamDesc_ ) , "::" + , stringify ! ( pointer ) )); } impl Clone for FT_StreamDesc_ { fn clone(&self) -> Self { *self } } -pub use self::FT_StreamDesc_ as FT_StreamDesc; +pub type FT_StreamDesc = FT_StreamDesc_; pub type FT_Stream_IoFunc = ::std::option::Option ::std::os::raw::c_ulong>; pub type FT_Stream_CloseFunc = ::std::option::Option; -pub use self::FT_StreamRec_ as FT_StreamRec; +pub type FT_StreamRec = FT_StreamRec_; pub type FT_Pos = ::std::os::raw::c_long; #[repr(C)] #[derive(Debug, Copy)] @@ -218,13 +303,25 @@ pub struct FT_Vector_ { } #[test] fn bindgen_test_layout_FT_Vector_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_Vector_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Vector_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Vector_ ) ) . x as * const _ as usize + } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Vector_ ) , "::" , + stringify ! ( x ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Vector_ ) ) . y as * const _ as usize + } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Vector_ ) , "::" , + stringify ! ( y ) )); } impl Clone for FT_Vector_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Vector_ as FT_Vector; +pub type FT_Vector = FT_Vector_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_BBox_ { @@ -235,13 +332,35 @@ pub struct FT_BBox_ { } #[test] fn bindgen_test_layout_FT_BBox_() { - assert_eq!(::std::mem::size_of::() , 32usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 32usize , concat ! ( + "Size of: " , stringify ! ( FT_BBox_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_BBox_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_BBox_ ) ) . xMin as * const _ as usize + } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_BBox_ ) , "::" , + stringify ! ( xMin ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_BBox_ ) ) . yMin as * const _ as usize + } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_BBox_ ) , "::" , + stringify ! ( yMin ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_BBox_ ) ) . xMax as * const _ as usize + } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_BBox_ ) , "::" , + stringify ! ( xMax ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_BBox_ ) ) . yMax as * const _ as usize + } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_BBox_ ) , "::" , + stringify ! ( yMax ) )); } impl Clone for FT_BBox_ { fn clone(&self) -> Self { *self } } -pub use self::FT_BBox_ as FT_BBox; +pub type FT_BBox = FT_BBox_; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum FT_Pixel_Mode_ { @@ -270,13 +389,55 @@ pub struct FT_Bitmap_ { } #[test] fn bindgen_test_layout_FT_Bitmap_() { - assert_eq!(::std::mem::size_of::() , 40usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 40usize , concat ! ( + "Size of: " , stringify ! ( FT_Bitmap_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Bitmap_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . rows as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( rows ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . width as * const _ as + usize } , 4usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( width ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . pitch as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( pitch ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . buffer as * const _ as + usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( buffer ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . num_grays as * const _ + as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( num_grays ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . pixel_mode as * const _ + as usize } , 26usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( pixel_mode ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . palette_mode as * const + _ as usize } , 27usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( palette_mode ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_ ) ) . palette as * const _ as + usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_ ) , "::" , + stringify ! ( palette ) )); } impl Clone for FT_Bitmap_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Bitmap_ as FT_Bitmap; +pub type FT_Bitmap = FT_Bitmap_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Outline_ { @@ -289,13 +450,45 @@ pub struct FT_Outline_ { } #[test] fn bindgen_test_layout_FT_Outline_() { - assert_eq!(::std::mem::size_of::() , 40usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 40usize , concat ! ( + "Size of: " , stringify ! ( FT_Outline_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Outline_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . n_contours as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( n_contours ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . n_points as * const _ + as usize } , 2usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( n_points ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . points as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( points ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . tags as * const _ as + usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( tags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . contours as * const _ + as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( contours ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_ ) ) . flags as * const _ as + usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_ ) , "::" , + stringify ! ( flags ) )); } impl Clone for FT_Outline_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Outline_ as FT_Outline; +pub type FT_Outline = FT_Outline_; pub type FT_Outline_MoveToFunc = ::std::option::Option() , 48usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 48usize , concat ! + ( "Size of: " , stringify ! ( FT_Outline_Funcs_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat + ! ( "Alignment of " , stringify ! ( FT_Outline_Funcs_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . move_to as * + const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( move_to ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . line_to as * + const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( line_to ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . conic_to as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( conic_to ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . cubic_to as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( cubic_to ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . shift as * const + _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( shift ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Outline_Funcs_ ) ) . delta as * const + _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Outline_Funcs_ ) , + "::" , stringify ! ( delta ) )); } impl Clone for FT_Outline_Funcs_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Outline_Funcs_ as FT_Outline_Funcs; +pub type FT_Outline_Funcs = FT_Outline_Funcs_; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum FT_Glyph_Format_ { @@ -349,12 +574,9 @@ pub enum FT_Glyph_Format_ { } pub use self::FT_Glyph_Format_ as FT_Glyph_Format; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_RasterRec_ { - pub _address: u8, -} -impl Clone for FT_RasterRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Raster = *mut FT_RasterRec_; #[repr(C)] @@ -366,13 +588,30 @@ pub struct FT_Span_ { } #[test] fn bindgen_test_layout_FT_Span_() { - assert_eq!(::std::mem::size_of::() , 6usize); - assert_eq!(::std::mem::align_of::() , 2usize); + assert_eq!(::std::mem::size_of::() , 6usize , concat ! ( + "Size of: " , stringify ! ( FT_Span_ ) )); + assert_eq! (::std::mem::align_of::() , 2usize , concat ! ( + "Alignment of " , stringify ! ( FT_Span_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Span_ ) ) . x as * const _ as usize } + , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Span_ ) , "::" , + stringify ! ( x ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Span_ ) ) . len as * const _ as usize + } , 2usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Span_ ) , "::" , + stringify ! ( len ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Span_ ) ) . coverage as * const _ as + usize } , 4usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Span_ ) , "::" , + stringify ! ( coverage ) )); } impl Clone for FT_Span_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Span_ as FT_Span; +pub type FT_Span = FT_Span_; pub type FT_SpanFunc = ::std::option::Option() , 96usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 96usize , concat ! + ( "Size of: " , stringify ! ( FT_Raster_Params_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat + ! ( "Alignment of " , stringify ! ( FT_Raster_Params_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . target as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( target ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . source as * const + _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( source ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . flags as * const + _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . gray_spans as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( gray_spans ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . black_spans as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( black_spans ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . bit_test as * + const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( bit_test ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . bit_set as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( bit_set ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . user as * const _ + as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( user ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Params_ ) ) . clip_box as * + const _ as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Params_ ) , + "::" , stringify ! ( clip_box ) )); } impl Clone for FT_Raster_Params_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Raster_Params_ as FT_Raster_Params; +pub type FT_Raster_Params = FT_Raster_Params_; pub type FT_Raster_NewFunc = ::std::option::Option() , 48usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 48usize , concat ! + ( "Size of: " , stringify ! ( FT_Raster_Funcs_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_Raster_Funcs_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . glyph_format as * + const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( glyph_format ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . raster_new as * + const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( raster_new ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . raster_reset as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( raster_reset ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . raster_set_mode as + * const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( raster_set_mode ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . raster_render as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( raster_render ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Raster_Funcs_ ) ) . raster_done as * + const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Raster_Funcs_ ) , + "::" , stringify ! ( raster_done ) )); } impl Clone for FT_Raster_Funcs_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Raster_Funcs_ as FT_Raster_Funcs; +pub type FT_Raster_Funcs = FT_Raster_Funcs_; pub type FT_Bool = ::std::os::raw::c_uchar; pub type FT_FWord = ::std::os::raw::c_short; pub type FT_UFWord = ::std::os::raw::c_ushort; -pub type FT_Char = ::std::os::raw::c_char; +pub type FT_Char = ::std::os::raw::c_schar; pub type FT_Byte = ::std::os::raw::c_uchar; pub type FT_Bytes = *const FT_Byte; pub type FT_Tag = FT_UInt32; @@ -483,13 +801,25 @@ pub struct FT_UnitVector_ { } #[test] fn bindgen_test_layout_FT_UnitVector_() { - assert_eq!(::std::mem::size_of::() , 4usize); - assert_eq!(::std::mem::align_of::() , 2usize); + assert_eq!(::std::mem::size_of::() , 4usize , concat ! ( + "Size of: " , stringify ! ( FT_UnitVector_ ) )); + assert_eq! (::std::mem::align_of::() , 2usize , concat ! ( + "Alignment of " , stringify ! ( FT_UnitVector_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_UnitVector_ ) ) . x as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_UnitVector_ ) , "::" + , stringify ! ( x ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_UnitVector_ ) ) . y as * const _ as + usize } , 2usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_UnitVector_ ) , "::" + , stringify ! ( y ) )); } impl Clone for FT_UnitVector_ { fn clone(&self) -> Self { *self } } -pub use self::FT_UnitVector_ as FT_UnitVector; +pub type FT_UnitVector = FT_UnitVector_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Matrix_ { @@ -500,13 +830,35 @@ pub struct FT_Matrix_ { } #[test] fn bindgen_test_layout_FT_Matrix_() { - assert_eq!(::std::mem::size_of::() , 32usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 32usize , concat ! ( + "Size of: " , stringify ! ( FT_Matrix_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Matrix_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Matrix_ ) ) . xx as * const _ as usize + } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Matrix_ ) , "::" , + stringify ! ( xx ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Matrix_ ) ) . xy as * const _ as usize + } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Matrix_ ) , "::" , + stringify ! ( xy ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Matrix_ ) ) . yx as * const _ as usize + } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Matrix_ ) , "::" , + stringify ! ( yx ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Matrix_ ) ) . yy as * const _ as usize + } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Matrix_ ) , "::" , + stringify ! ( yy ) )); } impl Clone for FT_Matrix_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Matrix_ as FT_Matrix; +pub type FT_Matrix = FT_Matrix_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Data_ { @@ -515,13 +867,25 @@ pub struct FT_Data_ { } #[test] fn bindgen_test_layout_FT_Data_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_Data_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Data_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Data_ ) ) . pointer as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Data_ ) , "::" , + stringify ! ( pointer ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Data_ ) ) . length as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Data_ ) , "::" , + stringify ! ( length ) )); } impl Clone for FT_Data_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Data_ as FT_Data; +pub type FT_Data = FT_Data_; pub type FT_Generic_Finalizer = ::std::option::Option; @@ -533,13 +897,25 @@ pub struct FT_Generic_ { } #[test] fn bindgen_test_layout_FT_Generic_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_Generic_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Generic_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Generic_ ) ) . data as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Generic_ ) , "::" , + stringify ! ( data ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Generic_ ) ) . finalizer as * const _ + as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Generic_ ) , "::" , + stringify ! ( finalizer ) )); } impl Clone for FT_Generic_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Generic_ as FT_Generic; +pub type FT_Generic = FT_Generic_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_ListNodeRec_ { @@ -549,8 +925,25 @@ pub struct FT_ListNodeRec_ { } #[test] fn bindgen_test_layout_FT_ListNodeRec_() { - assert_eq!(::std::mem::size_of::() , 24usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 24usize , concat ! ( + "Size of: " , stringify ! ( FT_ListNodeRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_ListNodeRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_ListNodeRec_ ) ) . prev as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_ListNodeRec_ ) , + "::" , stringify ! ( prev ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_ListNodeRec_ ) ) . next as * const _ + as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_ListNodeRec_ ) , + "::" , stringify ! ( next ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_ListNodeRec_ ) ) . data as * const _ + as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_ListNodeRec_ ) , + "::" , stringify ! ( data ) )); } impl Clone for FT_ListNodeRec_ { fn clone(&self) -> Self { *self } @@ -564,233 +957,238 @@ pub struct FT_ListRec_ { } #[test] fn bindgen_test_layout_FT_ListRec_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_ListRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_ListRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_ListRec_ ) ) . head as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_ListRec_ ) , "::" , + stringify ! ( head ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_ListRec_ ) ) . tail as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_ListRec_ ) , "::" , + stringify ! ( tail ) )); } impl Clone for FT_ListRec_ { fn clone(&self) -> Self { *self } } pub type FT_List = *mut FT_ListRec_; -pub use self::FT_ListNodeRec_ as FT_ListNodeRec; -pub use self::FT_ListRec_ as FT_ListRec; -pub const FT_Mod_Err_Base: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Autofit: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_BDF: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Bzip2: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Cache: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_CFF: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_CID: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Gzip: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_LZW: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_OTvalid: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_PCF: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_PFR: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_PSaux: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_PShinter: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_PSnames: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Raster: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_SFNT: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Smooth: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_TrueType: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Type1: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Type42: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Winfonts: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_GXvalid: _bindgen_ty_19 = - _bindgen_ty_19::FT_Mod_Err_Base; -pub const FT_Mod_Err_Max: _bindgen_ty_19 = _bindgen_ty_19::FT_Mod_Err_Max; +pub type FT_ListNodeRec = FT_ListNodeRec_; +pub type FT_ListRec = FT_ListRec_; +pub const FT_Mod_Err_Base: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Autofit: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_BDF: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Bzip2: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Cache: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_CFF: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_CID: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Gzip: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_LZW: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_OTvalid: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_PCF: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_PFR: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_PSaux: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_PShinter: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_PSnames: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Raster: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_SFNT: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Smooth: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_TrueType: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Type1: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Type42: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Winfonts: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_GXvalid: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Base; +pub const FT_Mod_Err_Max: _bindgen_ty_1 = _bindgen_ty_1::FT_Mod_Err_Max; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_19 { FT_Mod_Err_Base = 0, FT_Mod_Err_Max = 1, } -pub const FT_Err_Ok: _bindgen_ty_20 = _bindgen_ty_20::FT_Err_Ok; -pub const FT_Err_Cannot_Open_Resource: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Cannot_Open_Resource; -pub const FT_Err_Unknown_File_Format: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Unknown_File_Format; -pub const FT_Err_Invalid_File_Format: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_File_Format; -pub const FT_Err_Invalid_Version: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Version; -pub const FT_Err_Lower_Module_Version: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Lower_Module_Version; -pub const FT_Err_Invalid_Argument: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Argument; -pub const FT_Err_Unimplemented_Feature: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Unimplemented_Feature; -pub const FT_Err_Invalid_Table: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Table; -pub const FT_Err_Invalid_Offset: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Offset; -pub const FT_Err_Array_Too_Large: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Array_Too_Large; -pub const FT_Err_Missing_Module: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Module; -pub const FT_Err_Missing_Property: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Property; -pub const FT_Err_Invalid_Glyph_Index: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Glyph_Index; -pub const FT_Err_Invalid_Character_Code: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Character_Code; -pub const FT_Err_Invalid_Glyph_Format: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Glyph_Format; -pub const FT_Err_Cannot_Render_Glyph: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Cannot_Render_Glyph; -pub const FT_Err_Invalid_Outline: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Outline; -pub const FT_Err_Invalid_Composite: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Composite; -pub const FT_Err_Too_Many_Hints: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Hints; -pub const FT_Err_Invalid_Pixel_Size: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Pixel_Size; -pub const FT_Err_Invalid_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Handle; -pub const FT_Err_Invalid_Library_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Library_Handle; -pub const FT_Err_Invalid_Driver_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Driver_Handle; -pub const FT_Err_Invalid_Face_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Face_Handle; -pub const FT_Err_Invalid_Size_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Size_Handle; -pub const FT_Err_Invalid_Slot_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Slot_Handle; -pub const FT_Err_Invalid_CharMap_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_CharMap_Handle; -pub const FT_Err_Invalid_Cache_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Cache_Handle; -pub const FT_Err_Invalid_Stream_Handle: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Stream_Handle; -pub const FT_Err_Too_Many_Drivers: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Drivers; -pub const FT_Err_Too_Many_Extensions: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Extensions; -pub const FT_Err_Out_Of_Memory: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Out_Of_Memory; -pub const FT_Err_Unlisted_Object: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Unlisted_Object; -pub const FT_Err_Cannot_Open_Stream: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Cannot_Open_Stream; -pub const FT_Err_Invalid_Stream_Seek: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Stream_Seek; -pub const FT_Err_Invalid_Stream_Skip: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Stream_Skip; -pub const FT_Err_Invalid_Stream_Read: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Stream_Read; -pub const FT_Err_Invalid_Stream_Operation: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Stream_Operation; -pub const FT_Err_Invalid_Frame_Operation: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Frame_Operation; -pub const FT_Err_Nested_Frame_Access: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Nested_Frame_Access; -pub const FT_Err_Invalid_Frame_Read: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Frame_Read; -pub const FT_Err_Raster_Uninitialized: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Raster_Uninitialized; -pub const FT_Err_Raster_Corrupted: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Raster_Corrupted; -pub const FT_Err_Raster_Overflow: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Raster_Overflow; -pub const FT_Err_Raster_Negative_Height: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Raster_Negative_Height; -pub const FT_Err_Too_Many_Caches: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Caches; -pub const FT_Err_Invalid_Opcode: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Opcode; -pub const FT_Err_Too_Few_Arguments: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Few_Arguments; -pub const FT_Err_Stack_Overflow: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Stack_Overflow; -pub const FT_Err_Code_Overflow: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Code_Overflow; -pub const FT_Err_Bad_Argument: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Bad_Argument; -pub const FT_Err_Divide_By_Zero: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Divide_By_Zero; -pub const FT_Err_Invalid_Reference: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Reference; -pub const FT_Err_Debug_OpCode: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Debug_OpCode; -pub const FT_Err_ENDF_In_Exec_Stream: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_ENDF_In_Exec_Stream; -pub const FT_Err_Nested_DEFS: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Nested_DEFS; -pub const FT_Err_Invalid_CodeRange: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_CodeRange; -pub const FT_Err_Execution_Too_Long: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Execution_Too_Long; -pub const FT_Err_Too_Many_Function_Defs: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Function_Defs; -pub const FT_Err_Too_Many_Instruction_Defs: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Too_Many_Instruction_Defs; -pub const FT_Err_Table_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Table_Missing; -pub const FT_Err_Horiz_Header_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Horiz_Header_Missing; -pub const FT_Err_Locations_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Locations_Missing; -pub const FT_Err_Name_Table_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Name_Table_Missing; -pub const FT_Err_CMap_Table_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_CMap_Table_Missing; -pub const FT_Err_Hmtx_Table_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Hmtx_Table_Missing; -pub const FT_Err_Post_Table_Missing: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Post_Table_Missing; -pub const FT_Err_Invalid_Horiz_Metrics: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Horiz_Metrics; -pub const FT_Err_Invalid_CharMap_Format: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_CharMap_Format; -pub const FT_Err_Invalid_PPem: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_PPem; -pub const FT_Err_Invalid_Vert_Metrics: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Vert_Metrics; -pub const FT_Err_Could_Not_Find_Context: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Could_Not_Find_Context; -pub const FT_Err_Invalid_Post_Table_Format: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Post_Table_Format; -pub const FT_Err_Invalid_Post_Table: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Invalid_Post_Table; -pub const FT_Err_Syntax_Error: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Syntax_Error; -pub const FT_Err_Stack_Underflow: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Stack_Underflow; -pub const FT_Err_Ignore: _bindgen_ty_20 = _bindgen_ty_20::FT_Err_Ignore; -pub const FT_Err_No_Unicode_Glyph_Name: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_No_Unicode_Glyph_Name; -pub const FT_Err_Glyph_Too_Big: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Glyph_Too_Big; -pub const FT_Err_Missing_Startfont_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Startfont_Field; -pub const FT_Err_Missing_Font_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Font_Field; -pub const FT_Err_Missing_Size_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Size_Field; -pub const FT_Err_Missing_Fontboundingbox_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Fontboundingbox_Field; -pub const FT_Err_Missing_Chars_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Chars_Field; -pub const FT_Err_Missing_Startchar_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Startchar_Field; -pub const FT_Err_Missing_Encoding_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Encoding_Field; -pub const FT_Err_Missing_Bbx_Field: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Missing_Bbx_Field; -pub const FT_Err_Bbx_Too_Big: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Bbx_Too_Big; -pub const FT_Err_Corrupted_Font_Header: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Corrupted_Font_Header; -pub const FT_Err_Corrupted_Font_Glyphs: _bindgen_ty_20 = - _bindgen_ty_20::FT_Err_Corrupted_Font_Glyphs; -pub const FT_Err_Max: _bindgen_ty_20 = _bindgen_ty_20::FT_Err_Max; +pub enum _bindgen_ty_1 { FT_Mod_Err_Base = 0, FT_Mod_Err_Max = 1, } +pub const FT_Err_Ok: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Ok; +pub const FT_Err_Cannot_Open_Resource: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Cannot_Open_Resource; +pub const FT_Err_Unknown_File_Format: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Unknown_File_Format; +pub const FT_Err_Invalid_File_Format: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_File_Format; +pub const FT_Err_Invalid_Version: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Version; +pub const FT_Err_Lower_Module_Version: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Lower_Module_Version; +pub const FT_Err_Invalid_Argument: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Argument; +pub const FT_Err_Unimplemented_Feature: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Unimplemented_Feature; +pub const FT_Err_Invalid_Table: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Table; +pub const FT_Err_Invalid_Offset: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Offset; +pub const FT_Err_Array_Too_Large: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Array_Too_Large; +pub const FT_Err_Missing_Module: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Module; +pub const FT_Err_Missing_Property: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Property; +pub const FT_Err_Invalid_Glyph_Index: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Glyph_Index; +pub const FT_Err_Invalid_Character_Code: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Character_Code; +pub const FT_Err_Invalid_Glyph_Format: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Glyph_Format; +pub const FT_Err_Cannot_Render_Glyph: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Cannot_Render_Glyph; +pub const FT_Err_Invalid_Outline: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Outline; +pub const FT_Err_Invalid_Composite: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Composite; +pub const FT_Err_Too_Many_Hints: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Hints; +pub const FT_Err_Invalid_Pixel_Size: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Pixel_Size; +pub const FT_Err_Invalid_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Handle; +pub const FT_Err_Invalid_Library_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Library_Handle; +pub const FT_Err_Invalid_Driver_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Driver_Handle; +pub const FT_Err_Invalid_Face_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Face_Handle; +pub const FT_Err_Invalid_Size_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Size_Handle; +pub const FT_Err_Invalid_Slot_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Slot_Handle; +pub const FT_Err_Invalid_CharMap_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_CharMap_Handle; +pub const FT_Err_Invalid_Cache_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Cache_Handle; +pub const FT_Err_Invalid_Stream_Handle: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Stream_Handle; +pub const FT_Err_Too_Many_Drivers: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Drivers; +pub const FT_Err_Too_Many_Extensions: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Extensions; +pub const FT_Err_Out_Of_Memory: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Out_Of_Memory; +pub const FT_Err_Unlisted_Object: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Unlisted_Object; +pub const FT_Err_Cannot_Open_Stream: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Cannot_Open_Stream; +pub const FT_Err_Invalid_Stream_Seek: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Stream_Seek; +pub const FT_Err_Invalid_Stream_Skip: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Stream_Skip; +pub const FT_Err_Invalid_Stream_Read: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Stream_Read; +pub const FT_Err_Invalid_Stream_Operation: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Stream_Operation; +pub const FT_Err_Invalid_Frame_Operation: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Frame_Operation; +pub const FT_Err_Nested_Frame_Access: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Nested_Frame_Access; +pub const FT_Err_Invalid_Frame_Read: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Frame_Read; +pub const FT_Err_Raster_Uninitialized: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Raster_Uninitialized; +pub const FT_Err_Raster_Corrupted: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Raster_Corrupted; +pub const FT_Err_Raster_Overflow: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Raster_Overflow; +pub const FT_Err_Raster_Negative_Height: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Raster_Negative_Height; +pub const FT_Err_Too_Many_Caches: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Caches; +pub const FT_Err_Invalid_Opcode: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Opcode; +pub const FT_Err_Too_Few_Arguments: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Few_Arguments; +pub const FT_Err_Stack_Overflow: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Stack_Overflow; +pub const FT_Err_Code_Overflow: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Code_Overflow; +pub const FT_Err_Bad_Argument: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Bad_Argument; +pub const FT_Err_Divide_By_Zero: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Divide_By_Zero; +pub const FT_Err_Invalid_Reference: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Reference; +pub const FT_Err_Debug_OpCode: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Debug_OpCode; +pub const FT_Err_ENDF_In_Exec_Stream: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_ENDF_In_Exec_Stream; +pub const FT_Err_Nested_DEFS: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Nested_DEFS; +pub const FT_Err_Invalid_CodeRange: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_CodeRange; +pub const FT_Err_Execution_Too_Long: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Execution_Too_Long; +pub const FT_Err_Too_Many_Function_Defs: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Function_Defs; +pub const FT_Err_Too_Many_Instruction_Defs: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Too_Many_Instruction_Defs; +pub const FT_Err_Table_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Table_Missing; +pub const FT_Err_Horiz_Header_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Horiz_Header_Missing; +pub const FT_Err_Locations_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Locations_Missing; +pub const FT_Err_Name_Table_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Name_Table_Missing; +pub const FT_Err_CMap_Table_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_CMap_Table_Missing; +pub const FT_Err_Hmtx_Table_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Hmtx_Table_Missing; +pub const FT_Err_Post_Table_Missing: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Post_Table_Missing; +pub const FT_Err_Invalid_Horiz_Metrics: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Horiz_Metrics; +pub const FT_Err_Invalid_CharMap_Format: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_CharMap_Format; +pub const FT_Err_Invalid_PPem: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_PPem; +pub const FT_Err_Invalid_Vert_Metrics: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Vert_Metrics; +pub const FT_Err_Could_Not_Find_Context: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Could_Not_Find_Context; +pub const FT_Err_Invalid_Post_Table_Format: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Post_Table_Format; +pub const FT_Err_Invalid_Post_Table: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Invalid_Post_Table; +pub const FT_Err_Syntax_Error: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Syntax_Error; +pub const FT_Err_Stack_Underflow: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Stack_Underflow; +pub const FT_Err_Ignore: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Ignore; +pub const FT_Err_No_Unicode_Glyph_Name: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_No_Unicode_Glyph_Name; +pub const FT_Err_Glyph_Too_Big: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Glyph_Too_Big; +pub const FT_Err_Missing_Startfont_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Startfont_Field; +pub const FT_Err_Missing_Font_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Font_Field; +pub const FT_Err_Missing_Size_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Size_Field; +pub const FT_Err_Missing_Fontboundingbox_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Fontboundingbox_Field; +pub const FT_Err_Missing_Chars_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Chars_Field; +pub const FT_Err_Missing_Startchar_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Startchar_Field; +pub const FT_Err_Missing_Encoding_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Encoding_Field; +pub const FT_Err_Missing_Bbx_Field: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Missing_Bbx_Field; +pub const FT_Err_Bbx_Too_Big: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Bbx_Too_Big; +pub const FT_Err_Corrupted_Font_Header: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Corrupted_Font_Header; +pub const FT_Err_Corrupted_Font_Glyphs: _bindgen_ty_2 = + _bindgen_ty_2::FT_Err_Corrupted_Font_Glyphs; +pub const FT_Err_Max: _bindgen_ty_2 = _bindgen_ty_2::FT_Err_Max; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _bindgen_ty_20 { +pub enum _bindgen_ty_2 { FT_Err_Ok = 0, FT_Err_Cannot_Open_Resource = 1, FT_Err_Unknown_File_Format = 2, @@ -898,13 +1296,55 @@ pub struct FT_Glyph_Metrics_ { } #[test] fn bindgen_test_layout_FT_Glyph_Metrics_() { - assert_eq!(::std::mem::size_of::() , 64usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 64usize , concat ! + ( "Size of: " , stringify ! ( FT_Glyph_Metrics_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat + ! ( "Alignment of " , stringify ! ( FT_Glyph_Metrics_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . width as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( width ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . height as * const + _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . horiBearingX as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( horiBearingX ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . horiBearingY as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( horiBearingY ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . horiAdvance as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( horiAdvance ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . vertBearingX as * + const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( vertBearingX ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . vertBearingY as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( vertBearingY ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Glyph_Metrics_ ) ) . vertAdvance as * + const _ as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Glyph_Metrics_ ) , + "::" , stringify ! ( vertAdvance ) )); } impl Clone for FT_Glyph_Metrics_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Glyph_Metrics_ as FT_Glyph_Metrics; +pub type FT_Glyph_Metrics = FT_Glyph_Metrics_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Bitmap_Size_ { @@ -916,47 +1356,62 @@ pub struct FT_Bitmap_Size_ { } #[test] fn bindgen_test_layout_FT_Bitmap_Size_() { - assert_eq!(::std::mem::size_of::() , 32usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 32usize , concat ! ( + "Size of: " , stringify ! ( FT_Bitmap_Size_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_Bitmap_Size_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_Size_ ) ) . height as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_Size_ ) , + "::" , stringify ! ( height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_Size_ ) ) . width as * const _ + as usize } , 2usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_Size_ ) , + "::" , stringify ! ( width ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_Size_ ) ) . size as * const _ + as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_Size_ ) , + "::" , stringify ! ( size ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_Size_ ) ) . x_ppem as * const _ + as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_Size_ ) , + "::" , stringify ! ( x_ppem ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Bitmap_Size_ ) ) . y_ppem as * const _ + as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Bitmap_Size_ ) , + "::" , stringify ! ( y_ppem ) )); } impl Clone for FT_Bitmap_Size_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Bitmap_Size_ as FT_Bitmap_Size; +pub type FT_Bitmap_Size = FT_Bitmap_Size_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_LibraryRec_ { - pub _address: u8, -} -impl Clone for FT_LibraryRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Library = *mut FT_LibraryRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_ModuleRec_ { - pub _address: u8, -} -impl Clone for FT_ModuleRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Module = *mut FT_ModuleRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_DriverRec_ { - pub _address: u8, -} -impl Clone for FT_DriverRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Driver = *mut FT_DriverRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_RendererRec_ { - pub _address: u8, -} -impl Clone for FT_RendererRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Renderer = *mut FT_RendererRec_; #[repr(C)] @@ -996,8 +1451,165 @@ pub struct FT_FaceRec_ { } #[test] fn bindgen_test_layout_FT_FaceRec_() { - assert_eq!(::std::mem::size_of::() , 248usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 248usize , concat ! ( + "Size of: " , stringify ! ( FT_FaceRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_FaceRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . num_faces as * const _ + as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( num_faces ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . face_index as * const _ + as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( face_index ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . face_flags as * const _ + as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( face_flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . style_flags as * const + _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( style_flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . num_glyphs as * const _ + as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( num_glyphs ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . family_name as * const + _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( family_name ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . style_name as * const _ + as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( style_name ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . num_fixed_sizes as * + const _ as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( num_fixed_sizes ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . available_sizes as * + const _ as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( available_sizes ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . num_charmaps as * const + _ as usize } , 72usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( num_charmaps ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . charmaps as * const _ + as usize } , 80usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( charmaps ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . generic as * const _ as + usize } , 88usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( generic ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . bbox as * const _ as + usize } , 104usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( bbox ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . units_per_EM as * const + _ as usize } , 136usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( units_per_EM ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . ascender as * const _ + as usize } , 138usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( ascender ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . descender as * const _ + as usize } , 140usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( descender ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . height as * const _ as + usize } , 142usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . max_advance_width as * + const _ as usize } , 144usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( max_advance_width ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . max_advance_height as * + const _ as usize } , 146usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( max_advance_height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . underline_position as * + const _ as usize } , 148usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( underline_position ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . underline_thickness as + * const _ as usize } , 150usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( underline_thickness ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . glyph as * const _ as + usize } , 152usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( glyph ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . size as * const _ as + usize } , 160usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( size ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . charmap as * const _ as + usize } , 168usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( charmap ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . driver as * const _ as + usize } , 176usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( driver ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . memory as * const _ as + usize } , 184usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( memory ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . stream as * const _ as + usize } , 192usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( stream ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . sizes_list as * const _ + as usize } , 200usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( sizes_list ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . autohint as * const _ + as usize } , 216usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( autohint ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . extensions as * const _ + as usize } , 232usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( extensions ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_FaceRec_ ) ) . internal as * const _ + as usize } , 240usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_FaceRec_ ) , "::" , + stringify ! ( internal ) )); } impl Clone for FT_FaceRec_ { fn clone(&self) -> Self { *self } @@ -1013,8 +1625,30 @@ pub struct FT_SizeRec_ { } #[test] fn bindgen_test_layout_FT_SizeRec_() { - assert_eq!(::std::mem::size_of::() , 88usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 88usize , concat ! ( + "Size of: " , stringify ! ( FT_SizeRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_SizeRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_SizeRec_ ) ) . face as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_SizeRec_ ) , "::" , + stringify ! ( face ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_SizeRec_ ) ) . generic as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_SizeRec_ ) , "::" , + stringify ! ( generic ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_SizeRec_ ) ) . metrics as * const _ as + usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_SizeRec_ ) , "::" , + stringify ! ( metrics ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_SizeRec_ ) ) . internal as * const _ + as usize } , 80usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_SizeRec_ ) , "::" , + stringify ! ( internal ) )); } impl Clone for FT_SizeRec_ { fn clone(&self) -> Self { *self } @@ -1048,8 +1682,120 @@ pub struct FT_GlyphSlotRec_ { } #[test] fn bindgen_test_layout_FT_GlyphSlotRec_() { - assert_eq!(::std::mem::size_of::() , 304usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 304usize , concat ! + ( "Size of: " , stringify ! ( FT_GlyphSlotRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_GlyphSlotRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . library as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( library ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . face as * const _ + as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( face ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . next as * const _ + as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( next ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . reserved as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( reserved ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . generic as * const + _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( generic ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . metrics as * const + _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( metrics ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . linearHoriAdvance + as * const _ as usize } , 112usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( linearHoriAdvance ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . linearVertAdvance + as * const _ as usize } , 120usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( linearVertAdvance ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . advance as * const + _ as usize } , 128usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( advance ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . format as * const + _ as usize } , 144usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( format ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . bitmap as * const + _ as usize } , 152usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( bitmap ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . bitmap_left as * + const _ as usize } , 192usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( bitmap_left ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . bitmap_top as * + const _ as usize } , 196usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( bitmap_top ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . outline as * const + _ as usize } , 200usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( outline ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . num_subglyphs as * + const _ as usize } , 240usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( num_subglyphs ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . subglyphs as * + const _ as usize } , 248usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( subglyphs ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . control_data as * + const _ as usize } , 256usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( control_data ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . control_len as * + const _ as usize } , 264usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( control_len ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . lsb_delta as * + const _ as usize } , 272usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( lsb_delta ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . rsb_delta as * + const _ as usize } , 280usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( rsb_delta ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . other as * const _ + as usize } , 288usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( other ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_GlyphSlotRec_ ) ) . internal as * + const _ as usize } , 296usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_GlyphSlotRec_ ) , + "::" , stringify ! ( internal ) )); } impl Clone for FT_GlyphSlotRec_ { fn clone(&self) -> Self { *self } @@ -1065,8 +1811,30 @@ pub struct FT_CharMapRec_ { } #[test] fn bindgen_test_layout_FT_CharMapRec_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_CharMapRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_CharMapRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_CharMapRec_ ) ) . face as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_CharMapRec_ ) , "::" + , stringify ! ( face ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_CharMapRec_ ) ) . encoding as * const + _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_CharMapRec_ ) , "::" + , stringify ! ( encoding ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_CharMapRec_ ) ) . platform_id as * + const _ as usize } , 12usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_CharMapRec_ ) , "::" + , stringify ! ( platform_id ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_CharMapRec_ ) ) . encoding_id as * + const _ as usize } , 14usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_CharMapRec_ ) , "::" + , stringify ! ( encoding_id ) )); } impl Clone for FT_CharMapRec_ { fn clone(&self) -> Self { *self } @@ -1101,24 +1869,18 @@ pub enum FT_Encoding_ { FT_ENCODING_APPLE_ROMAN = 1634889070, } pub use self::FT_Encoding_ as FT_Encoding; -pub use self::FT_CharMapRec_ as FT_CharMapRec; +pub type FT_CharMapRec = FT_CharMapRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_Face_InternalRec_ { - pub _address: u8, -} -impl Clone for FT_Face_InternalRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Face_Internal = *mut FT_Face_InternalRec_; -pub use self::FT_FaceRec_ as FT_FaceRec; +pub type FT_FaceRec = FT_FaceRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_Size_InternalRec_ { - pub _address: u8, -} -impl Clone for FT_Size_InternalRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Size_Internal = *mut FT_Size_InternalRec_; #[repr(C)] @@ -1135,33 +1897,69 @@ pub struct FT_Size_Metrics_ { } #[test] fn bindgen_test_layout_FT_Size_Metrics_() { - assert_eq!(::std::mem::size_of::() , 56usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 56usize , concat ! + ( "Size of: " , stringify ! ( FT_Size_Metrics_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_Size_Metrics_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . x_ppem as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( x_ppem ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . y_ppem as * const + _ as usize } , 2usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( y_ppem ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . x_scale as * const + _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( x_scale ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . y_scale as * const + _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( y_scale ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . ascender as * + const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( ascender ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . descender as * + const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( descender ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . height as * const + _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_Metrics_ ) ) . max_advance as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_Metrics_ ) , + "::" , stringify ! ( max_advance ) )); } impl Clone for FT_Size_Metrics_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Size_Metrics_ as FT_Size_Metrics; -pub use self::FT_SizeRec_ as FT_SizeRec; +pub type FT_Size_Metrics = FT_Size_Metrics_; +pub type FT_SizeRec = FT_SizeRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_SubGlyphRec_ { - pub _address: u8, -} -impl Clone for FT_SubGlyphRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_SubGlyph = *mut FT_SubGlyphRec_; #[repr(C)] -#[derive(Debug, Copy)] +#[derive(Debug, Copy, Clone)] pub struct FT_Slot_InternalRec_ { - pub _address: u8, -} -impl Clone for FT_Slot_InternalRec_ { - fn clone(&self) -> Self { *self } + _unused: [u8; 0], } pub type FT_Slot_Internal = *mut FT_Slot_InternalRec_; -pub use self::FT_GlyphSlotRec_ as FT_GlyphSlotRec; +pub type FT_GlyphSlotRec = FT_GlyphSlotRec_; extern "C" { pub fn FT_Init_FreeType(alibrary: *mut FT_Library) -> FT_Error; } @@ -1176,13 +1974,25 @@ pub struct FT_Parameter_ { } #[test] fn bindgen_test_layout_FT_Parameter_() { - assert_eq!(::std::mem::size_of::() , 16usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 16usize , concat ! ( + "Size of: " , stringify ! ( FT_Parameter_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Parameter_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Parameter_ ) ) . tag as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Parameter_ ) , "::" + , stringify ! ( tag ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Parameter_ ) ) . data as * const _ as + usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Parameter_ ) , "::" + , stringify ! ( data ) )); } impl Clone for FT_Parameter_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Parameter_ as FT_Parameter; +pub type FT_Parameter = FT_Parameter_; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Open_Args_ { @@ -1197,13 +2007,55 @@ pub struct FT_Open_Args_ { } #[test] fn bindgen_test_layout_FT_Open_Args_() { - assert_eq!(::std::mem::size_of::() , 64usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 64usize , concat ! ( + "Size of: " , stringify ! ( FT_Open_Args_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( + "Alignment of " , stringify ! ( FT_Open_Args_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . flags as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . memory_base as * + const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( memory_base ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . memory_size as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( memory_size ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . pathname as * const _ + as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( pathname ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . stream as * const _ + as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( stream ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . driver as * const _ + as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( driver ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . num_params as * const + _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( num_params ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Open_Args_ ) ) . params as * const _ + as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Open_Args_ ) , "::" + , stringify ! ( params ) )); } impl Clone for FT_Open_Args_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Open_Args_ as FT_Open_Args; +pub type FT_Open_Args = FT_Open_Args_; extern "C" { pub fn FT_New_Face(library: FT_Library, filepathname: *const ::std::os::raw::c_char, @@ -1258,13 +2110,41 @@ pub struct FT_Size_RequestRec_ { } #[test] fn bindgen_test_layout_FT_Size_RequestRec_() { - assert_eq!(::std::mem::size_of::() , 32usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 32usize , concat + ! ( "Size of: " , stringify ! ( FT_Size_RequestRec_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , + concat ! ( + "Alignment of " , stringify ! ( FT_Size_RequestRec_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_RequestRec_ ) ) . type_ as * + const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_RequestRec_ ) , + "::" , stringify ! ( type_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_RequestRec_ ) ) . width as * + const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_RequestRec_ ) , + "::" , stringify ! ( width ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_RequestRec_ ) ) . height as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_RequestRec_ ) , + "::" , stringify ! ( height ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_RequestRec_ ) ) . horiResolution + as * const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_RequestRec_ ) , + "::" , stringify ! ( horiResolution ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Size_RequestRec_ ) ) . vertResolution + as * const _ as usize } , 28usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Size_RequestRec_ ) , + "::" , stringify ! ( vertResolution ) )); } impl Clone for FT_Size_RequestRec_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Size_RequestRec_ as FT_Size_RequestRec; +pub type FT_Size_RequestRec = FT_Size_RequestRec_; pub type FT_Size_Request = *mut FT_Size_RequestRec_; extern "C" { pub fn FT_Request_Size(face: FT_Face, req: FT_Size_Request) -> FT_Error; @@ -1475,14 +2355,14 @@ extern "C" { pub type FT_Module_Interface = FT_Pointer; pub type FT_Module_Constructor = ::std::option::Option ::std::os::raw::c_int>; + -> FT_Error>; pub type FT_Module_Destructor = ::std::option::Option; pub type FT_Module_Requester = ::std::option::Option *mut ::std::os::raw::c_void>; + -> FT_Module_Interface>; #[repr(C)] #[derive(Debug, Copy)] pub struct FT_Module_Class_ { @@ -1498,13 +2378,60 @@ pub struct FT_Module_Class_ { } #[test] fn bindgen_test_layout_FT_Module_Class_() { - assert_eq!(::std::mem::size_of::() , 72usize); - assert_eq!(::std::mem::align_of::() , 8usize); + assert_eq!(::std::mem::size_of::() , 72usize , concat ! + ( "Size of: " , stringify ! ( FT_Module_Class_ ) )); + assert_eq! (::std::mem::align_of::() , 8usize , concat ! + ( "Alignment of " , stringify ! ( FT_Module_Class_ ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_flags as * + const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_flags ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_size as * + const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_size ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_name as * + const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_name ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_version as + * const _ as usize } , 24usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_version ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_requires as + * const _ as usize } , 32usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_requires ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_interface + as * const _ as usize } , 40usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_interface ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_init as * + const _ as usize } , 48usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_init ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . module_done as * + const _ as usize } , 56usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( module_done ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const FT_Module_Class_ ) ) . get_interface as * + const _ as usize } , 64usize , concat ! ( + "Alignment of field: " , stringify ! ( FT_Module_Class_ ) , + "::" , stringify ! ( get_interface ) )); } impl Clone for FT_Module_Class_ { fn clone(&self) -> Self { *self } } -pub use self::FT_Module_Class_ as FT_Module_Class; +pub type FT_Module_Class = FT_Module_Class_; extern "C" { pub fn FT_Add_Module(library: FT_Library, clazz: *const FT_Module_Class) -> FT_Error; @@ -1560,3 +2487,82 @@ extern "C" { pub fn FT_Get_TrueType_Engine_Type(library: FT_Library) -> FT_TrueTypeEngineType; } +extern "C" { + pub fn FT_Outline_Decompose(outline: *mut FT_Outline, + func_interface: *const FT_Outline_Funcs, + user: *mut ::std::os::raw::c_void) + -> FT_Error; +} +extern "C" { + pub fn FT_Outline_New(library: FT_Library, numPoints: FT_UInt, + numContours: FT_Int, anoutline: *mut FT_Outline) + -> FT_Error; +} +extern "C" { + pub fn FT_Outline_New_Internal(memory: FT_Memory, numPoints: FT_UInt, + numContours: FT_Int, + anoutline: *mut FT_Outline) -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Done(library: FT_Library, outline: *mut FT_Outline) + -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Done_Internal(memory: FT_Memory, + outline: *mut FT_Outline) -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Check(outline: *mut FT_Outline) -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Get_CBox(outline: *const FT_Outline, + acbox: *mut FT_BBox); +} +extern "C" { + pub fn FT_Outline_Translate(outline: *const FT_Outline, xOffset: FT_Pos, + yOffset: FT_Pos); +} +extern "C" { + pub fn FT_Outline_Copy(source: *const FT_Outline, target: *mut FT_Outline) + -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Transform(outline: *const FT_Outline, + matrix: *const FT_Matrix); +} +extern "C" { + pub fn FT_Outline_Embolden(outline: *mut FT_Outline, strength: FT_Pos) + -> FT_Error; +} +extern "C" { + pub fn FT_Outline_EmboldenXY(outline: *mut FT_Outline, xstrength: FT_Pos, + ystrength: FT_Pos) -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Reverse(outline: *mut FT_Outline); +} +extern "C" { + pub fn FT_Outline_Get_Bitmap(library: FT_Library, + outline: *mut FT_Outline, + abitmap: *const FT_Bitmap) -> FT_Error; +} +extern "C" { + pub fn FT_Outline_Render(library: FT_Library, outline: *mut FT_Outline, + params: *mut FT_Raster_Params) -> FT_Error; +} +pub const FT_Orientation__FT_ORIENTATION_FILL_RIGHT: FT_Orientation_ = + FT_Orientation_::FT_ORIENTATION_TRUETYPE; +pub const FT_Orientation__FT_ORIENTATION_FILL_LEFT: FT_Orientation_ = + FT_Orientation_::FT_ORIENTATION_POSTSCRIPT; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum FT_Orientation_ { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_NONE = 2, +} +pub use self::FT_Orientation_ as FT_Orientation; +extern "C" { + pub fn FT_Outline_Get_Orientation(outline: *mut FT_Outline) + -> FT_Orientation; +} diff --git a/third_party/rust/fxhash/.cargo-checksum.json b/third_party/rust/fxhash/.cargo-checksum.json new file mode 100644 index 000000000000..eee1486249b2 --- /dev/null +++ b/third_party/rust/fxhash/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"83bb4c3e7fbfb7380c175923ba7dfe150e4e09bd4ebfb45e65e5f8a494d36ab9","README.md":"7b9227f966b312e221bd372fef79438b2446a21241eb7542520eac29bfbc10d0","bench.rs":"b4dc3ef9eeb043ffb470b37a0c2a36306a024af808eac8517924359298d3e183","lib.rs":"885b72a1c977dc1c3ff4e0652719e62b6d8c3e713403e571afd581283f72df7b"},"package":"c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"} \ No newline at end of file diff --git a/third_party/rust/heapsize-0.3.8/.cargo-ok b/third_party/rust/fxhash/.cargo-ok similarity index 100% rename from third_party/rust/heapsize-0.3.8/.cargo-ok rename to third_party/rust/fxhash/.cargo-ok diff --git a/third_party/rust/fxhash/Cargo.toml b/third_party/rust/fxhash/Cargo.toml new file mode 100644 index 000000000000..ae86c78c460d --- /dev/null +++ b/third_party/rust/fxhash/Cargo.toml @@ -0,0 +1,38 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "fxhash" +version = "0.2.1" +authors = ["cbreeden "] +description = "A fast, non-secure, hashing algorithm derived from an internal hasher used in FireFox and Rustc." +documentation = "https://docs.rs/fxhash" +readme = "README.md" +keywords = ["hash"] +categories = ["algorithms"] +license = "Apache-2.0/MIT" +repository = "https://github.com/cbreeden/fxhash" + +[lib] +name = "fxhash" +path = "lib.rs" + +[[bench]] +name = "fxhash" +path = "bench.rs" +[dependencies.byteorder] +version = "1.0.0" +[dev-dependencies.seahash] +version = "3.0.5" + +[dev-dependencies.fnv] +version = "1.0.5" diff --git a/third_party/rust/fxhash/README.md b/third_party/rust/fxhash/README.md new file mode 100644 index 000000000000..672568ab12c8 --- /dev/null +++ b/third_party/rust/fxhash/README.md @@ -0,0 +1,62 @@ +# Fx Hash + +This hashing algorithm was extracted from the Rustc compiler. This is the same hashing algoirthm used for some internal operations in FireFox. The strength of this algorithm is in hashing 8 bytes at a time on 64-bit platforms, where the FNV algorithm works on one byte at a time. + +## Disclaimer + +It is **not a cryptographically secure** hash, so it is strongly recommended that you do not use this hash for cryptographic purproses. Furthermore, this hashing algorithm was not designed to prevent any attacks for determining collisions which could be used to potentially cause quadratic behavior in `HashMap`s. So it is not recommended to expose this hash in places where collissions or DDOS attacks may be a concern. + +## Examples + +Building an Fx backed hashmap. + +```rust +extern crate fxhash; +use fxhash::FxHashMap; + +let mut hashmap = FxHashMap::new(); + +hashmap.insert("black", 0); +hashmap.insert("white", 255); +``` + +Building an Fx backed hashset. + +```rust +extern crate fxhash; +use fxhash::FxHashSet; + +let mut hashmap = FxHashSet::new(); + +hashmap.insert("black"); +hashmap.insert("white"); +``` + +## Benchmarks + +Generally `fxhash` is than `fnv` on `u32`, `u64`, or any byte sequence with length >= 5. However, keep in mind that hashing speed is not the only characteristic worth considering. That being said, Rustc had an observable increase in speed when switching from `fnv` backed hashmaps to `fx` based hashmaps. + + bench_fnv_003 ... bench: 3 ns/iter (+/- 0) + bench_fnv_004 ... bench: 2 ns/iter (+/- 0) + bench_fnv_011 ... bench: 6 ns/iter (+/- 1) + bench_fnv_012 ... bench: 5 ns/iter (+/- 1) + bench_fnv_023 ... bench: 14 ns/iter (+/- 3) + bench_fnv_024 ... bench: 14 ns/iter (+/- 4) + bench_fnv_068 ... bench: 57 ns/iter (+/- 11) + bench_fnv_132 ... bench: 145 ns/iter (+/- 30) + bench_fx_003 ... bench: 4 ns/iter (+/- 0) + bench_fx_004 ... bench: 3 ns/iter (+/- 1) + bench_fx_011 ... bench: 5 ns/iter (+/- 2) + bench_fx_012 ... bench: 4 ns/iter (+/- 1) + bench_fx_023 ... bench: 7 ns/iter (+/- 3) + bench_fx_024 ... bench: 4 ns/iter (+/- 1) + bench_fx_068 ... bench: 10 ns/iter (+/- 3) + bench_fx_132 ... bench: 19 ns/iter (+/- 5) + bench_seahash_003 ... bench: 30 ns/iter (+/- 12) + bench_seahash_004 ... bench: 32 ns/iter (+/- 22) + bench_seahash_011 ... bench: 30 ns/iter (+/- 4) + bench_seahash_012 ... bench: 31 ns/iter (+/- 1) + bench_seahash_023 ... bench: 32 ns/iter (+/- 6) + bench_seahash_024 ... bench: 31 ns/iter (+/- 5) + bench_seahash_068 ... bench: 40 ns/iter (+/- 9) + bench_seahash_132 ... bench: 50 ns/iter (+/- 12) \ No newline at end of file diff --git a/third_party/rust/fxhash/bench.rs b/third_party/rust/fxhash/bench.rs new file mode 100644 index 000000000000..b54395497cb9 --- /dev/null +++ b/third_party/rust/fxhash/bench.rs @@ -0,0 +1,78 @@ +#![feature(test)] +extern crate test; +extern crate fnv; +extern crate fxhash; +extern crate seahash; + +use std::hash::{Hash, Hasher}; +use test::{Bencher, black_box}; + + +fn fnvhash(b: H) -> u64 { + let mut hasher = fnv::FnvHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +fn seahash(b: H) -> u64 { + let mut hasher = seahash::SeaHasher::default(); + b.hash(&mut hasher); + hasher.finish() +} + +macro_rules! generate_benches { + ($($fx:ident, $fx32:ident, $fx64:ident, $fnv:ident, $sea:ident, $s:expr),* $(,)*) => ( + $( + #[bench] + fn $fx(b: &mut Bencher) { + let s = black_box($s); + b.iter(|| { + fxhash::hash(&s) + }) + } + + #[bench] + fn $fx32(b: &mut Bencher) { + let s = black_box($s); + b.iter(|| { + fxhash::hash32(&s) + }) + } + + #[bench] + fn $fx64(b: &mut Bencher) { + let s = black_box($s); + b.iter(|| { + fxhash::hash64(&s) + }) + } + + #[bench] + fn $fnv(b: &mut Bencher) { + let s = black_box($s); + b.iter(|| { + fnvhash(&s) + }) + } + + #[bench] + fn $sea(b: &mut Bencher) { + let s = black_box($s); + b.iter(|| { + seahash(&s) + }) + } + )* + ) +} + +generate_benches!( + bench_fx_003, bench_fx32_003, bench_fx64_003, bench_fnv_003, bench_seahash_003, "123", + bench_fx_004, bench_fx32_004, bench_fx64_004, bench_fnv_004, bench_seahash_004, "1234", + bench_fx_011, bench_fx32_011, bench_fx64_011, bench_fnv_011, bench_seahash_011, "12345678901", + bench_fx_012, bench_fx32_012, bench_fx64_012, bench_fnv_012, bench_seahash_012, "123456789012", + bench_fx_023, bench_fx32_023, bench_fx64_023, bench_fnv_023, bench_seahash_023, "12345678901234567890123", + bench_fx_024, bench_fx32_024, bench_fx64_024, bench_fnv_024, bench_seahash_024, "123456789012345678901234", + bench_fx_068, bench_fx32_068, bench_fx64_068, bench_fnv_068, bench_seahash_068, "11234567890123456789012345678901234567890123456789012345678901234567", + bench_fx_132, bench_fx32_132, bench_fx64_132, bench_fnv_132, bench_seahash_132, "112345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901", +); \ No newline at end of file diff --git a/third_party/rust/fxhash/lib.rs b/third_party/rust/fxhash/lib.rs new file mode 100644 index 000000000000..22eb88c8d2a6 --- /dev/null +++ b/third_party/rust/fxhash/lib.rs @@ -0,0 +1,324 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(missing_docs)] + +//! # Fx Hash +//! +//! This hashing algorithm was extracted from the Rustc compiler. This is the same hashing +//! algoirthm used for some internal operations in FireFox. The strength of this algorithm +//! is in hashing 8 bytes at a time on 64-bit platforms, where the FNV algorithm works on one +//! byte at a time. +//! +//! ## Disclaimer +//! +//! It is **not a cryptographically secure** hash, so it is strongly recommended that you do +//! not use this hash for cryptographic purproses. Furthermore, this hashing algorithm was +//! not designed to prevent any attacks for determining collisions which could be used to +//! potentially cause quadratic behavior in `HashMap`s. So it is not recommended to expose +//! this hash in places where collissions or DDOS attacks may be a concern. + +use std::collections::{HashMap, HashSet}; +use std::default::Default; +use std::hash::{Hasher, Hash, BuildHasherDefault}; +use std::ops::BitXor; + +extern crate byteorder; +use byteorder::{ByteOrder, NativeEndian}; + +/// A builder for default Fx hashers. +pub type FxBuildHasher = BuildHasherDefault; + +/// A `HashMap` using a default Fx hasher. +pub type FxHashMap = HashMap; + +/// A `HashSet` using a default Fx hasher. +pub type FxHashSet = HashSet; + +const ROTATE: u32 = 5; +const SEED64: u64 = 0x517cc1b727220a95; +const SEED32: u32 = (SEED64 & 0xFFFF_FFFF) as u32; + +#[cfg(target_pointer_width = "32")] +const SEED: usize = SEED32 as usize; +#[cfg(target_pointer_width = "64")] +const SEED: usize = SEED64 as usize; + +trait HashWord { + fn hash_word(&mut self, Self); +} + +macro_rules! impl_hash_word { + ($($ty:ty = $key:ident),* $(,)*) => ( + $( + impl HashWord for $ty { + #[inline] + fn hash_word(&mut self, word: Self) { + *self = self.rotate_left(ROTATE).bitxor(word).wrapping_mul($key); + } + } + )* + ) +} + +impl_hash_word!(usize = SEED, u32 = SEED32, u64 = SEED64); + +#[inline] +fn write32(mut hash: u32, mut bytes: &[u8]) -> u32 { + while bytes.len() >= 4 { + let n = NativeEndian::read_u32(bytes); + hash.hash_word(n); + bytes = bytes.split_at(4).1; + } + + for byte in bytes { + hash.hash_word(*byte as u32); + } + hash +} + +#[inline] +fn write64(mut hash: u64, mut bytes: &[u8]) -> u64 { + while bytes.len() >= 8 { + let n = NativeEndian::read_u64(bytes); + hash.hash_word(n); + bytes = bytes.split_at(8).1; + } + + if bytes.len() >= 4 { + let n = NativeEndian::read_u32(bytes); + hash.hash_word(n as u64); + bytes = bytes.split_at(4).1; + } + + for byte in bytes { + hash.hash_word(*byte as u64); + } + hash +} + +#[inline] +#[cfg(target_pointer_width = "32")] +fn write(hash: usize, bytes: &[u8]) -> usize { + write32(hash as u32, bytes) as usize +} + +#[inline] +#[cfg(target_pointer_width = "64")] +fn write(hash: usize, bytes: &[u8]) -> usize { + write64(hash as u64, bytes) as usize +} + +/// This hashing algorithm was extracted from the Rustc compiler. +/// This is the same hashing algoirthm used for some internal operations in FireFox. +/// The strength of this algorithm is in hashing 8 bytes at a time on 64-bit platforms, +/// where the FNV algorithm works on one byte at a time. +/// +/// This hashing algorithm should not be used for cryptographic, or in scenarios where +/// DOS attacks are a concern. +#[derive(Debug, Clone)] +pub struct FxHasher { + hash: usize, +} + +impl Default for FxHasher { + #[inline] + fn default() -> FxHasher { + FxHasher { hash: 0 } + } +} + +impl Hasher for FxHasher { + #[inline] + fn write(&mut self, bytes: &[u8]) { + self.hash = write(self.hash, bytes); + } + + #[inline] + fn write_u8(&mut self, i: u8) { + self.hash.hash_word(i as usize); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.hash.hash_word(i as usize); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.hash.hash_word(i as usize); + } + + #[inline] + #[cfg(target_pointer_width = "32")] + fn write_u64(&mut self, i: u64) { + self.hash.hash_word(i as usize); + self.hash.hash_word((i >> 32) as usize); + } + + #[inline] + #[cfg(target_pointer_width = "64")] + fn write_u64(&mut self, i: u64) { + self.hash.hash_word(i as usize); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.hash.hash_word(i); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash as u64 + } +} + +/// This hashing algorithm was extracted from the Rustc compiler. +/// This is the same hashing algoirthm used for some internal operations in FireFox. +/// The strength of this algorithm is in hashing 8 bytes at a time on any platform, +/// where the FNV algorithm works on one byte at a time. +/// +/// This hashing algorithm should not be used for cryptographic, or in scenarios where +/// DOS attacks are a concern. +#[derive(Debug, Clone)] +pub struct FxHasher64 { + hash: u64, +} + +impl Default for FxHasher64 { + #[inline] + fn default() -> FxHasher64 { + FxHasher64 { hash: 0 } + } +} + +impl Hasher for FxHasher64 { + #[inline] + fn write(&mut self, bytes: &[u8]) { + self.hash = write64(self.hash, bytes); + } + + #[inline] + fn write_u8(&mut self, i: u8) { + self.hash.hash_word(i as u64); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.hash.hash_word(i as u64); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.hash.hash_word(i as u64); + } + + fn write_u64(&mut self, i: u64) { + self.hash.hash_word(i); + } + + #[inline] + fn write_usize(&mut self, i: usize) { + self.hash.hash_word(i as u64); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash + } +} + +/// This hashing algorithm was extracted from the Rustc compiler. +/// This is the same hashing algoirthm used for some internal operations in FireFox. +/// The strength of this algorithm is in hashing 4 bytes at a time on any platform, +/// where the FNV algorithm works on one byte at a time. +/// +/// This hashing algorithm should not be used for cryptographic, or in scenarios where +/// DOS attacks are a concern. +#[derive(Debug, Clone)] +pub struct FxHasher32 { + hash: u32, +} + +impl Default for FxHasher32 { + #[inline] + fn default() -> FxHasher32 { + FxHasher32 { hash: 0 } + } +} + +impl Hasher for FxHasher32 { + #[inline] + fn write(&mut self, bytes: &[u8]) { + self.hash = write32(self.hash, bytes); + } + + #[inline] + fn write_u8(&mut self, i: u8) { + self.hash.hash_word(i as u32); + } + + #[inline] + fn write_u16(&mut self, i: u16) { + self.hash.hash_word(i as u32); + } + + #[inline] + fn write_u32(&mut self, i: u32) { + self.hash.hash_word(i); + } + + #[inline] + fn write_u64(&mut self, i: u64) { + self.hash.hash_word(i as u32); + self.hash.hash_word((i >> 32) as u32); + } + + #[inline] + #[cfg(target_pointer_width = "32")] + fn write_usize(&mut self, i: usize) { + self.write_u32(i as u32); + } + + #[inline] + #[cfg(target_pointer_width = "64")] + fn write_usize(&mut self, i: usize) { + self.write_u64(i as u64); + } + + #[inline] + fn finish(&self) -> u64 { + self.hash as u64 + } +} + +/// A convenience function for when you need a quick 64-bit hash. +#[inline] +pub fn hash64(v: &T) -> u64 { + let mut state = FxHasher64::default(); + v.hash(&mut state); + state.finish() +} + +/// A convenience function for when you need a quick 32-bit hash. +#[inline] +pub fn hash32(v: &T) -> u32 { + let mut state = FxHasher32::default(); + v.hash(&mut state); + state.finish() as u32 +} + +/// A convenience function for when you need a quick usize hash. +#[inline] +pub fn hash(v: &T) -> usize { + let mut state = FxHasher::default(); + v.hash(&mut state); + state.finish() as usize +} \ No newline at end of file diff --git a/third_party/rust/heapsize-0.3.8/.cargo-checksum.json b/third_party/rust/heapsize-0.3.8/.cargo-checksum.json deleted file mode 100644 index 56bda6aaf04b..000000000000 --- a/third_party/rust/heapsize-0.3.8/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"1108708721703f4562646e1e7c6f6c924fa997835714bcc6a3ff8a58382134f1","Cargo.toml":"723e5918946fdb518ed1ad3e03ae9104b980cbe85bbee1989dc4197570ba6d73","README.md":"9a38b16bccde5db28c34d79134f02d2cdcbbab224b9a68ace93c5b85b5ef38f2","appveyor.yml":"130e820ab60abf8d08f3a91d4b0158e6a581c180385e12850113adb362eb158c","build.rs":"e13e88ed285a829256d3c6987563a663c37e335457d090125a3e19b1a97fec8e","src/lib.rs":"ab4e0a2e6d0ac700df5dbb7a2c83542cb82c94d4e46c632a4114fec93d6aba0a","tests/tests.rs":"f642da7b54b6cde55cf25fe84b2e6b27356d26b351d42a38e944b93e0c1fa24f"},"package":"5a376f7402b85be6e0ba504243ecbc0709c48019ecc6286d0540c2e359050c88"} \ No newline at end of file diff --git a/third_party/rust/heapsize-0.3.8/.travis.yml b/third_party/rust/heapsize-0.3.8/.travis.yml deleted file mode 100644 index ef8e20c3ffe5..000000000000 --- a/third_party/rust/heapsize-0.3.8/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: rust -rust: - - 1.8.0 - - nightly - - beta - - stable - -os: - - linux - - osx - -notifications: - webhooks: http://build.servo.org:54856/travis - -script: - - cargo test - - "[ $TRAVIS_RUST_VERSION != nightly ] || cargo test --features unstable" - - "[ $TRAVIS_RUST_VERSION != nightly ] || cargo test --manifest-path derive/Cargo.toml" - diff --git a/third_party/rust/heapsize-0.3.8/Cargo.toml b/third_party/rust/heapsize-0.3.8/Cargo.toml deleted file mode 100644 index 62be5b66b37a..000000000000 --- a/third_party/rust/heapsize-0.3.8/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "heapsize" -version = "0.3.8" -authors = [ "The Servo Project Developers" ] -description = "Infrastructure for measuring the total runtime size of an object on the heap" -license = "MPL-2.0" -repository = "https://github.com/servo/heapsize" -build = "build.rs" - -[target.'cfg(windows)'.dependencies] -kernel32-sys = "0.2.1" - -[features] -unstable = [] diff --git a/third_party/rust/heapsize-0.3.8/README.md b/third_party/rust/heapsize-0.3.8/README.md deleted file mode 100644 index f89a960cba85..000000000000 --- a/third_party/rust/heapsize-0.3.8/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# heapsize - -In support of measuring heap allocations in Rust programs. - -[API Documentation](https://doc.servo.org/heapsize/) diff --git a/third_party/rust/heapsize-0.3.8/appveyor.yml b/third_party/rust/heapsize-0.3.8/appveyor.yml deleted file mode 100644 index 595b08c2d166..000000000000 --- a/third_party/rust/heapsize-0.3.8/appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -environment: - matrix: - - FEATURES: "" - - FEATURES: "unstable" - -platform: - - i686-pc-windows-gnu - - i686-pc-windows-msvc - - x86_64-pc-windows-gnu - - x86_64-pc-windows-msvc - -install: - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:PLATFORM}.exe" - - rust-nightly-%PLATFORM%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin - - rustc -V - - cargo -V - -build_script: - - cargo build --verbose --features "%FEATURES%" - -test_script: - - cargo test --verbose --features "%FEATURES%" diff --git a/third_party/rust/heapsize-0.3.8/build.rs b/third_party/rust/heapsize-0.3.8/build.rs deleted file mode 100644 index 9e299e6b19d6..000000000000 --- a/third_party/rust/heapsize-0.3.8/build.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::env::var; -use std::process::Command; -use std::str; - -fn main() { - let verbose = Command::new(var("RUSTC").unwrap_or("rustc".into())) - .arg("--version") - .arg("--verbose") - .output() - .unwrap() - .stdout; - let verbose = str::from_utf8(&verbose).unwrap(); - let mut commit_date = None; - let mut release = None; - for line in verbose.lines() { - let mut parts = line.split(':'); - match parts.next().unwrap().trim() { - "commit-date" => commit_date = Some(parts.next().unwrap().trim()), - "release" => release = Some(parts.next().unwrap().trim()), - _ => {} - } - } - let version = release.unwrap().split('-').next().unwrap();; - let mut version_components = version.split('.').map(|s| s.parse::().unwrap()); - let version = ( - version_components.next().unwrap(), - version_components.next().unwrap(), - version_components.next().unwrap(), - // "unknown" sorts after "2016-02-14", which is what we want to defaut to unprefixed - // https://github.com/servo/heapsize/pull/44#issuecomment-187935883 - commit_date.unwrap() - ); - assert_eq!(version_components.next(), None); - if version < (1, 8, 0, "2016-02-14") { - println!("cargo:rustc-cfg=prefixed_jemalloc"); - } -} diff --git a/third_party/rust/heapsize-0.3.8/src/lib.rs b/third_party/rust/heapsize-0.3.8/src/lib.rs deleted file mode 100644 index d27789aa59e1..000000000000 --- a/third_party/rust/heapsize-0.3.8/src/lib.rs +++ /dev/null @@ -1,323 +0,0 @@ -/* 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/. */ - -//! Data structure measurement. - -#[cfg(target_os = "windows")] -extern crate kernel32; - -#[cfg(target_os = "windows")] -use kernel32::{GetProcessHeap, HeapSize, HeapValidate}; -use std::borrow::Cow; -use std::cell::{Cell, RefCell}; -use std::collections::{BTreeMap, HashSet, HashMap, LinkedList, VecDeque}; -use std::hash::BuildHasher; -use std::hash::Hash; -use std::marker::PhantomData; -use std::mem::size_of; -use std::net::{Ipv4Addr, Ipv6Addr}; -use std::os::raw::c_void; -use std::sync::Arc; -use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; -use std::rc::Rc; - -/// Get the size of a heap block. -/// -/// Ideally Rust would expose a function like this in std::rt::heap. -/// -/// `unsafe` because the caller must ensure that the pointer is from jemalloc. -/// FIXME: This probably interacts badly with custom allocators: -/// https://doc.rust-lang.org/book/custom-allocators.html -pub unsafe fn heap_size_of(ptr: *const c_void) -> usize { - if ptr == 0x01 as *const c_void { - 0 - } else { - heap_size_of_impl(ptr) - } -} - -#[cfg(not(target_os = "windows"))] -unsafe fn heap_size_of_impl(ptr: *const c_void) -> usize { - // The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some - // platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice - // this function doesn't modify the contents of the block that `ptr` points to, so we use - // `*const c_void` here. - extern "C" { - #[cfg_attr(any(prefixed_jemalloc, target_os = "macos", target_os = "android"), link_name = "je_malloc_usable_size")] - fn malloc_usable_size(ptr: *const c_void) -> usize; - } - malloc_usable_size(ptr) -} - -#[cfg(target_os = "windows")] -pub unsafe fn heap_size_of_impl(mut ptr: *const c_void) -> usize { - let heap = GetProcessHeap(); - - if HeapValidate(heap, 0, ptr) == 0 { - ptr = *(ptr as *const *const c_void).offset(-1); - } - - HeapSize(heap, 0, ptr) as usize -} - -// The simplest trait for measuring the size of heap data structures. More complex traits that -// return multiple measurements -- e.g. measure text separately from images -- are also possible, -// and should be used when appropriate. -// -pub trait HeapSizeOf { - /// Measure the size of any heap-allocated structures that hang off this value, but not the - /// space taken up by the value itself (i.e. what size_of:: measures, more or less); that - /// space is handled by the implementation of HeapSizeOf for Box below. - fn heap_size_of_children(&self) -> usize; -} - -// There are two possible ways to measure the size of `self` when it's on the heap: compute it -// (with `::std::rt::heap::usable_size(::std::mem::size_of::(), 0)`) or measure it directly -// using the heap allocator (with `heap_size_of`). We do the latter, for the following reasons. -// -// * The heap allocator is the true authority for the sizes of heap blocks; its measurement is -// guaranteed to be correct. In comparison, size computations are error-prone. (For example, the -// `rt::heap::usable_size` function used in some of Rust's non-default allocator implementations -// underestimate the true usable size of heap blocks, which is safe in general but would cause -// under-measurement here.) -// -// * If we measure something that isn't a heap block, we'll get a crash. This keeps us honest, -// which is important because unsafe code is involved and this can be gotten wrong. -// -// However, in the best case, the two approaches should give the same results. -// -impl HeapSizeOf for Box { - fn heap_size_of_children(&self) -> usize { - // Measure size of `self`. - unsafe { - heap_size_of(&**self as *const T as *const c_void) + (**self).heap_size_of_children() - } - } -} - -impl HeapSizeOf for [T] { - fn heap_size_of_children(&self) -> usize { - self.iter().fold(0, |size, item| size + item.heap_size_of_children()) - } -} - -impl HeapSizeOf for String { - fn heap_size_of_children(&self) -> usize { - unsafe { - heap_size_of(self.as_ptr() as *const c_void) - } - } -} - -impl<'a, T: ?Sized> HeapSizeOf for &'a T { - fn heap_size_of_children(&self) -> usize { - 0 - } -} - -impl HeapSizeOf for Option { - fn heap_size_of_children(&self) -> usize { - match *self { - None => 0, - Some(ref x) => x.heap_size_of_children() - } - } -} - -impl HeapSizeOf for Result { - fn heap_size_of_children(&self) -> usize { - match *self { - Ok(ref x) => x.heap_size_of_children(), - Err(ref e) => e.heap_size_of_children(), - } - } -} - -impl<'a, B: ?Sized + ToOwned> HeapSizeOf for Cow<'a, B> where B::Owned: HeapSizeOf { - fn heap_size_of_children(&self) -> usize { - match *self { - Cow::Borrowed(_) => 0, - Cow::Owned(ref b) => b.heap_size_of_children(), - } - } -} - -impl HeapSizeOf for () { - fn heap_size_of_children(&self) -> usize { - 0 - } -} - -impl HeapSizeOf for (T1, T2) - where T1: HeapSizeOf, T2 :HeapSizeOf -{ - fn heap_size_of_children(&self) -> usize { - self.0.heap_size_of_children() + - self.1.heap_size_of_children() - } -} - -impl HeapSizeOf for (T1, T2, T3) - where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf -{ - fn heap_size_of_children(&self) -> usize { - self.0.heap_size_of_children() + - self.1.heap_size_of_children() + - self.2.heap_size_of_children() - } -} - -impl HeapSizeOf for (T1, T2, T3, T4) - where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf, T4: HeapSizeOf -{ - fn heap_size_of_children(&self) -> usize { - self.0.heap_size_of_children() + - self.1.heap_size_of_children() + - self.2.heap_size_of_children() + - self.3.heap_size_of_children() - } -} - -impl HeapSizeOf for (T1, T2, T3, T4, T5) - where T1: HeapSizeOf, T2 :HeapSizeOf, T3: HeapSizeOf, T4: HeapSizeOf, T5: HeapSizeOf -{ - fn heap_size_of_children(&self) -> usize { - self.0.heap_size_of_children() + - self.1.heap_size_of_children() + - self.2.heap_size_of_children() + - self.3.heap_size_of_children() + - self.4.heap_size_of_children() - } -} - -impl HeapSizeOf for Arc { - fn heap_size_of_children(&self) -> usize { - (**self).heap_size_of_children() - } -} - -impl HeapSizeOf for RefCell { - fn heap_size_of_children(&self) -> usize { - self.borrow().heap_size_of_children() - } -} - -impl HeapSizeOf for Cell { - fn heap_size_of_children(&self) -> usize { - self.get().heap_size_of_children() - } -} - -impl HeapSizeOf for Vec { - fn heap_size_of_children(&self) -> usize { - self.iter().fold( - unsafe { heap_size_of(self.as_ptr() as *const c_void) }, - |n, elem| n + elem.heap_size_of_children()) - } -} - -impl HeapSizeOf for VecDeque { - fn heap_size_of_children(&self) -> usize { - self.iter().fold( - // FIXME: get the buffer pointer for heap_size_of(), capacity() is a lower bound: - self.capacity() * size_of::(), - |n, elem| n + elem.heap_size_of_children()) - } -} - -impl HeapSizeOf for Vec> { - fn heap_size_of_children(&self) -> usize { - // The fate of measuring Rc is still undecided, but we still want to measure - // the space used for storing them. - unsafe { - heap_size_of(self.as_ptr() as *const c_void) - } - } -} - -impl HeapSizeOf for HashSet - where T: Eq + Hash, S: BuildHasher { - fn heap_size_of_children(&self) -> usize { - //TODO(#6908) measure actual bucket memory usage instead of approximating - let size = self.capacity() * (size_of::() + size_of::()); - self.iter().fold(size, |n, value| { - n + value.heap_size_of_children() - }) - } -} - -impl HeapSizeOf for HashMap - where K: Eq + Hash, S: BuildHasher { - fn heap_size_of_children(&self) -> usize { - //TODO(#6908) measure actual bucket memory usage instead of approximating - let size = self.capacity() * (size_of::() + size_of::() + size_of::()); - self.iter().fold(size, |n, (key, value)| { - n + key.heap_size_of_children() + value.heap_size_of_children() - }) - } -} - -// PhantomData is always 0. -impl HeapSizeOf for PhantomData { - fn heap_size_of_children(&self) -> usize { - 0 - } -} - -// A linked list has an overhead of two words per item. -impl HeapSizeOf for LinkedList { - fn heap_size_of_children(&self) -> usize { - let mut size = 0; - for item in self { - size += 2 * size_of::() + size_of::() + item.heap_size_of_children(); - } - size - } -} - -// FIXME: Overhead for the BTreeMap nodes is not accounted for. -impl HeapSizeOf for BTreeMap { - fn heap_size_of_children(&self) -> usize { - let mut size = 0; - for (key, value) in self.iter() { - size += size_of::<(K, V)>() + - key.heap_size_of_children() + - value.heap_size_of_children(); - } - size - } -} - -/// For use on types defined in external crates -/// with known heap sizes. -#[macro_export] -macro_rules! known_heap_size( - ($size:expr, $($ty:ty),+) => ( - $( - impl $crate::HeapSizeOf for $ty { - #[inline(always)] - fn heap_size_of_children(&self) -> usize { - $size - } - } - )+ - ); - ($size: expr, $($ty:ident<$($gen:ident),+>),+) => ( - $( - impl<$($gen: $crate::HeapSizeOf),+> $crate::HeapSizeOf for $ty<$($gen),+> { - #[inline(always)] - fn heap_size_of_children(&self) -> usize { - $size - } - } - )+ - ); -); - -known_heap_size!(0, char, str); -known_heap_size!(0, u8, u16, u32, u64, usize); -known_heap_size!(0, i8, i16, i32, i64, isize); -known_heap_size!(0, bool, f32, f64); -known_heap_size!(0, AtomicBool, AtomicIsize, AtomicUsize); -known_heap_size!(0, Ipv4Addr, Ipv6Addr); diff --git a/third_party/rust/heapsize-0.3.8/tests/tests.rs b/third_party/rust/heapsize-0.3.8/tests/tests.rs deleted file mode 100644 index 97da29de7b7f..000000000000 --- a/third_party/rust/heapsize-0.3.8/tests/tests.rs +++ /dev/null @@ -1,171 +0,0 @@ -/* 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/. */ - -#![cfg_attr(feature= "unstable", feature(alloc, heap_api, repr_simd))] - -extern crate heapsize; - -use heapsize::{HeapSizeOf, heap_size_of}; -use std::os::raw::c_void; - -pub const EMPTY: *mut () = 0x1 as *mut (); - -#[cfg(feature = "unstable")] -mod unstable { - extern crate alloc; - - use heapsize::{HeapSizeOf, heap_size_of}; - use std::os::raw::c_void; - - #[repr(C, simd)] - struct OverAligned(u64, u64, u64, u64); - - #[test] - fn check_empty() { - assert_eq!(::EMPTY, alloc::heap::EMPTY); - } - - #[cfg(not(target_os = "windows"))] - #[test] - fn test_alloc() { - unsafe { - // A 64 byte request is allocated exactly. - let x = alloc::heap::allocate(64, 0); - assert_eq!(heap_size_of(x as *const c_void), 64); - alloc::heap::deallocate(x, 64, 0); - - // A 255 byte request is rounded up to 256 bytes. - let x = alloc::heap::allocate(255, 0); - assert_eq!(heap_size_of(x as *const c_void), 256); - alloc::heap::deallocate(x, 255, 0); - - // A 1MiB request is allocated exactly. - let x = alloc::heap::allocate(1024 * 1024, 0); - assert_eq!(heap_size_of(x as *const c_void), 1024 * 1024); - alloc::heap::deallocate(x, 1024 * 1024, 0); - - // An overaligned 1MiB request is allocated exactly. - let x = alloc::heap::allocate(1024 * 1024, 32); - assert_eq!(heap_size_of(x as *const c_void), 1024 * 1024); - alloc::heap::deallocate(x, 1024 * 1024, 32); - } - } - - #[cfg(target_os = "windows")] - #[test] - fn test_alloc() { - unsafe { - // A 64 byte request is allocated exactly. - let x = alloc::heap::allocate(64, 0); - assert_eq!(heap_size_of(x as *const c_void), 64); - alloc::heap::deallocate(x, 64, 0); - - // A 255 byte request is allocated exactly. - let x = alloc::heap::allocate(255, 0); - assert_eq!(heap_size_of(x as *const c_void), 255); - alloc::heap::deallocate(x, 255, 0); - - // A 1MiB request is allocated exactly. - let x = alloc::heap::allocate(1024 * 1024, 0); - assert_eq!(heap_size_of(x as *const c_void), 1024 * 1024); - alloc::heap::deallocate(x, 1024 * 1024, 0); - - // An overaligned 1MiB request is over-allocated. - let x = alloc::heap::allocate(1024 * 1024, 32); - assert_eq!(heap_size_of(x as *const c_void), 1024 * 1024 + 32); - alloc::heap::deallocate(x, 1024 * 1024, 32); - } - } - - #[cfg(not(target_os = "windows"))] - #[test] - fn test_simd() { - let x = Box::new(OverAligned(0, 0, 0, 0)); - assert_eq!(unsafe { heap_size_of(&*x as *const _ as *const c_void) }, 32); - } - - #[cfg(target_os = "windows")] - #[test] - fn test_simd() { - let x = Box::new(OverAligned(0, 0, 0, 0)); - assert_eq!(unsafe { heap_size_of(&*x as *const _ as *const c_void) }, 32 + 32); - } - - #[test] - fn test_boxed_str() { - let x = "raclette".to_owned().into_boxed_str(); - assert_eq!(x.heap_size_of_children(), 8); - } -} - -#[test] -fn test_heap_size() { - - // Note: jemalloc often rounds up request sizes. However, it does not round up for request - // sizes of 8 and higher that are powers of two. We take advantage of knowledge here to make - // the sizes of various heap-allocated blocks predictable. - - //----------------------------------------------------------------------- - // Start with basic heap block measurement. - - unsafe { - // EMPTY is the special non-null address used to represent zero-size allocations. - assert_eq!(heap_size_of(EMPTY as *const c_void), 0); - } - - //----------------------------------------------------------------------- - // Test HeapSizeOf implementations for various built-in types. - - // Not on the heap; 0 bytes. - let x = 0i64; - assert_eq!(x.heap_size_of_children(), 0); - - // An i64 is 8 bytes. - let x = Box::new(0i64); - assert_eq!(x.heap_size_of_children(), 8); - - // An ascii string with 16 chars is 16 bytes in UTF-8. - let string = String::from("0123456789abcdef"); - assert_eq!(string.heap_size_of_children(), 16); - - let string_ref: (&String, ()) = (&string, ()); - assert_eq!(string_ref.heap_size_of_children(), 0); - - let slice: &str = &*string; - assert_eq!(slice.heap_size_of_children(), 0); - - // Not on the heap. - let x: Option = None; - assert_eq!(x.heap_size_of_children(), 0); - - // Not on the heap. - let x = Some(0i64); - assert_eq!(x.heap_size_of_children(), 0); - - // The `Some` is not on the heap, but the Box is. - let x = Some(Box::new(0i64)); - assert_eq!(x.heap_size_of_children(), 8); - - // Not on the heap. - let x = ::std::sync::Arc::new(0i64); - assert_eq!(x.heap_size_of_children(), 0); - - // The `Arc` is not on the heap, but the Box is. - let x = ::std::sync::Arc::new(Box::new(0i64)); - assert_eq!(x.heap_size_of_children(), 8); - - // Zero elements, no heap storage. - let x: Vec = vec![]; - assert_eq!(x.heap_size_of_children(), 0); - - // Four elements, 8 bytes per element. - let x = vec![0i64, 1i64, 2i64, 3i64]; - assert_eq!(x.heap_size_of_children(), 32); -} - -#[test] -fn test_boxed_slice() { - let x = vec![1i64, 2i64].into_boxed_slice(); - assert_eq!(x.heap_size_of_children(), 16) -} diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index d06d5007212e..6ccee380f19d 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -343,7 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "freetype" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -354,6 +354,14 @@ name = "futures" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gamma-lut" version = "0.2.0" @@ -427,14 +435,6 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "heapsize" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "heapsize" version = "0.4.0" @@ -1208,8 +1208,8 @@ dependencies = [ "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1233,8 +1233,9 @@ dependencies = [ "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1307,14 +1308,14 @@ dependencies = [ "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03" "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" -"checksum freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fde23272c687e4570aefec06cb71174ec0f5284b725deac4e77ba2665d635faf" +"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7" "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a" +"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f72af1e933f296b827361eb9e70d0267abf8ad0de9ec7fa667bbe67177b297" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb" "checksum gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "917ee404f414ed77756c12cb44fdcc7cd02f207bf91e1dc91a3ce7da794ec361" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5a376f7402b85be6e0ba504243ecbc0709c48019ecc6286d0540c2e359050c88" "checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index 68a60679386d..5c4fbf5e8afe 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -341,7 +341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "freetype" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -352,6 +352,14 @@ name = "futures" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gamma-lut" version = "0.2.0" @@ -425,14 +433,6 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "heapsize" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "heapsize" version = "0.4.0" @@ -1195,8 +1195,8 @@ dependencies = [ "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1220,8 +1220,9 @@ dependencies = [ "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1294,14 +1295,14 @@ dependencies = [ "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03" "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff" "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" -"checksum freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fde23272c687e4570aefec06cb71174ec0f5284b725deac4e77ba2665d635faf" +"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7" "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a" +"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f72af1e933f296b827361eb9e70d0267abf8ad0de9ec7fa667bbe67177b297" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb" "checksum gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "917ee404f414ed77756c12cb44fdcc7cd02f207bf91e1dc91a3ce7da794ec361" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5a376f7402b85be6e0ba504243ecbc0709c48019ecc6286d0540c2e359050c88" "checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" From 1caf76088425a54b770733173d9e93bc313396e0 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:26 -0400 Subject: [PATCH 035/166] Bug 1385003 - Mark counter-style-rule-clone as failing from WR cset 921bde2. r=jrmuizel This was already marked fuzzy but now the difference between the test and reference images is even more pronounced. Technically this might still be fuzzable because the thickness of the text (which is what is different) is not what the test is testing for. But if we fuzz it the fuzz numbers would be so high that legitimate failures might get fuzzed as well, so it's better to just mark it failing for now and deal with it later. MozReview-Commit-ID: 3Wt32XB1TWG --HG-- extra : rebase_source : 5310a5b2deb187dcf0e4d3bc009bfae6abd1ef24 --- layout/reftests/stylesheet-cloning/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/stylesheet-cloning/reftest.list b/layout/reftests/stylesheet-cloning/reftest.list index a3286db2e6cc..dc628df8244d 100644 --- a/layout/reftests/stylesheet-cloning/reftest.list +++ b/layout/reftests/stylesheet-cloning/reftest.list @@ -1,4 +1,4 @@ -fuzzy-if(webrender,255-255,434-434) == counter-style-rule-clone.html glyphs-ref.html # passes trivially +fails-if(webrender) == counter-style-rule-clone.html glyphs-ref.html # passes trivially # because "Dynamic change on @counter-style not yet supported" == document-rule-clone.html shouldbegreen-ref.html == media-rule-clone.html shouldbegreen-ref.html From 4088068ad09af526150c6a012fbf1671ac583cbc Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:26 -0400 Subject: [PATCH 036/166] Bug 1385003 - Update webrender bindings for API changes in WR cset 55acc967. r=nical MozReview-Commit-ID: 3pW2ssFdb50 --HG-- extra : rebase_source : 22892c92f130ae429cce5c42f27b57068d9f08ee --- gfx/webrender_bindings/src/bindings.rs | 68 +++++++++++++++++--------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index c676c5e6bd84..bd2e25b8dfab 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -639,10 +639,12 @@ pub extern "C" fn wr_api_add_image(dh: &mut DocumentHandle, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - dh.api.add_image(image_key, - descriptor.into(), - ImageData::new(copied_bytes), - None); + let mut resources = ResourceUpdates::new(); + resources.add_image(image_key, + descriptor.into(), + ImageData::new(copied_bytes), + None); + dh.api.update_resources(resources); } #[no_mangle] @@ -652,10 +654,12 @@ pub extern "C" fn wr_api_add_blob_image(dh: &mut DocumentHandle, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - dh.api.add_image(image_key, - descriptor.into(), - ImageData::new_blob_image(copied_bytes), - None); + let mut resources = ResourceUpdates::new(); + resources.add_image(image_key, + descriptor.into(), + ImageData::new_blob_image(copied_bytes), + None); + dh.api.update_resources(resources); } #[no_mangle] @@ -666,14 +670,16 @@ pub extern "C" fn wr_api_add_external_image(dh: &mut DocumentHandle, buffer_type: WrExternalImageBufferType, channel_index: u8) { assert!(unsafe { is_in_compositor_thread() }); - dh.api.add_image(image_key, - descriptor.into(), - ImageData::External(ExternalImageData { + let mut resources = ResourceUpdates::new(); + resources.add_image(image_key, + descriptor.into(), + ImageData::External(ExternalImageData { id: external_image_id.into(), channel_index: channel_index, image_type: buffer_type, }), - None); + None); + dh.api.update_resources(resources); } #[no_mangle] @@ -684,7 +690,9 @@ pub extern "C" fn wr_api_update_image(dh: &mut DocumentHandle, assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - dh.api.update_image(key, descriptor.into(), ImageData::new(copied_bytes), None); + let mut resources = ResourceUpdates::new(); + resources.update_image(key, descriptor.into(), ImageData::new(copied_bytes), None); + dh.api.update_resources(resources); } #[no_mangle] @@ -706,7 +714,9 @@ pub extern "C" fn wr_api_update_external_image( } ); - dh.api.update_image(key, descriptor.into(), data, None); + let mut resources = ResourceUpdates::new(); + resources.update_image(key, descriptor.into(), data, None); + dh.api.update_resources(resources); } #[no_mangle] @@ -716,19 +726,23 @@ pub extern "C" fn wr_api_update_blob_image(dh: &mut DocumentHandle, bytes: ByteSlice) { assert!(unsafe { is_in_compositor_thread() }); let copied_bytes = bytes.as_slice().to_owned(); - dh.api.update_image( - image_key, - descriptor.into(), - ImageData::new_blob_image(copied_bytes), - None + let mut resources = ResourceUpdates::new(); + resources.update_image( + image_key, + descriptor.into(), + ImageData::new_blob_image(copied_bytes), + None ); + dh.api.update_resources(resources); } #[no_mangle] pub extern "C" fn wr_api_delete_image(dh: &mut DocumentHandle, key: WrImageKey) { assert!(unsafe { is_in_compositor_thread() }); - dh.api.delete_image(key) + let mut resources = ResourceUpdates::new(); + resources.delete_image(key); + dh.api.update_resources(resources); } #[no_mangle] @@ -779,7 +793,8 @@ pub unsafe extern "C" fn wr_api_set_root_display_list(dh: &mut DocumentHandle, color, LayoutSize::new(viewport_width, viewport_height), (pipeline_id, content_size.into(), dl), - preserve_frame_state); + preserve_frame_state, + ResourceUpdates::new()); } #[no_mangle] @@ -794,7 +809,8 @@ pub unsafe extern "C" fn wr_api_clear_root_display_list(dh: &mut DocumentHandle, None, LayoutSize::new(0.0, 0.0), frame_builder.dl_builder.finalize(), - preserve_frame_state); + preserve_frame_state, + ResourceUpdates::new()); } #[no_mangle] @@ -862,14 +878,18 @@ pub extern "C" fn wr_api_add_raw_font(dh: &mut DocumentHandle, let mut font_vector = Vec::new(); font_vector.extend_from_slice(font_slice); - dh.api.add_raw_font(key, font_vector, index); + let mut resources = ResourceUpdates::new(); + resources.add_raw_font(key, font_vector, index); + dh.api.update_resources(resources); } #[no_mangle] pub extern "C" fn wr_api_delete_font(dh: &mut DocumentHandle, key: WrFontKey) { assert!(unsafe { is_in_compositor_thread() }); - dh.api.delete_font(key); + let mut resources = ResourceUpdates::new(); + resources.delete_font(key); + dh.api.update_resources(resources); } #[no_mangle] From 01928f3eb3dd8b535c4dd953e837b740b7fa89ac Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 08:46:26 -0400 Subject: [PATCH 037/166] Bug 1385003 - Update webrender bindings for API change in WR cset c7a5b78d. r=nical MozReview-Commit-ID: DY5vwlv4JYM --HG-- extra : rebase_source : 265cce68c927833120dcc55c0a1b230f6e042efc --- gfx/webrender_bindings/src/bindings.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index bd2e25b8dfab..27a0bb0cb2e6 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -9,6 +9,7 @@ use gleam::gl; use webrender_api::*; use webrender::renderer::{ReadPixelsFormat, Renderer, RendererOptions}; use webrender::renderer::{ExternalImage, ExternalImageHandler, ExternalImageSource}; +use webrender::renderer::{DebugFlags, PROFILER_DBG}; use webrender::{ApiRecordingReceiver, BinaryRecorder}; use thread_profiler::register_thread_with_profiler; use moz2d_renderer::Moz2dImageRenderer; @@ -464,7 +465,9 @@ pub unsafe extern "C" fn wr_renderer_readback(renderer: &mut Renderer, #[no_mangle] pub extern "C" fn wr_renderer_set_profiler_enabled(renderer: &mut Renderer, enabled: bool) { - renderer.set_profiler_enabled(enabled); + let mut flags = renderer.get_debug_flags(); + flags.set(PROFILER_DBG, enabled); + renderer.set_debug_flags(flags); } #[no_mangle] @@ -574,10 +577,12 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId, Arc::clone(&(*thread_pool).0) }; + let mut debug_flags = DebugFlags::empty(); + debug_flags.set(PROFILER_DBG, enable_profiler); let opts = RendererOptions { enable_aa: true, enable_subpixel_aa: true, - enable_profiler: enable_profiler, + debug_flags: debug_flags, recorder: recorder, blob_image_renderer: Some(Box::new(Moz2dImageRenderer::new(workers.clone()))), workers: Some(workers.clone()), From be4742a4fb88bcfa4b0d027760ef1e19725692ee Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 10:46:53 -0400 Subject: [PATCH 038/166] Bug 1385003 - Add missing call to deinit the renderer before dropping it. r=kvark MozReview-Commit-ID: 3dmttqFqMJE --HG-- extra : rebase_source : 7e122d07e086e4ad26255079edf3e1de309b685b --- gfx/webrender_bindings/src/bindings.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 27a0bb0cb2e6..dbcebb4b76ae 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -485,7 +485,9 @@ pub extern "C" fn wr_renderer_current_epoch(renderer: &mut Renderer, /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC #[no_mangle] pub unsafe extern "C" fn wr_renderer_delete(renderer: *mut Renderer) { - Box::from_raw(renderer); + let renderer = Box::from_raw(renderer); + renderer.deinit(); + // let renderer go out of scope and get dropped } pub struct WrRenderedEpochs { From 813d290b574d68bb575d908b6de9d0b8bd96eb9d Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 8 Aug 2017 21:47:02 -0700 Subject: [PATCH 039/166] Bug 1387499 - Clear the servo bits when dropping servo data. r=emilio This fixes the testcase in the bug, which removes and reinserts some elements. Our invariants require us not to set the dirty descendants bits on unstyled elements. MozReview-Commit-ID: 1eESZjNSURG --- dom/base/Element.cpp | 3 +++ layout/base/ServoRestyleManager.cpp | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 6c3a7ab0c993..c87f0a6cb548 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -4123,8 +4123,11 @@ Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32 void Element::ClearServoData() { + MOZ_ASSERT(IsStyledByServo()); #ifdef MOZ_STYLO Servo_Element_ClearData(this); + UnsetFlags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO | + ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO); #else MOZ_CRASH("Accessing servo node data in non-stylo build"); #endif diff --git a/layout/base/ServoRestyleManager.cpp b/layout/base/ServoRestyleManager.cpp index f8c151181371..0b62a84e127d 100644 --- a/layout/base/ServoRestyleManager.cpp +++ b/layout/base/ServoRestyleManager.cpp @@ -252,8 +252,6 @@ ServoRestyleManager::ClearServoDataFromSubtree(Element* aElement) } aElement->ClearServoData(); - aElement->UnsetHasDirtyDescendantsForServo(); - aElement->UnsetHasAnimationOnlyDirtyDescendantsForServo(); } /* static */ void From 9fb54004da3adf22ec6938b81ab3fa0fd888eee2 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 8 Aug 2017 20:28:52 -0700 Subject: [PATCH 040/166] Bug 1387499 - Crashtest. r=me MozReview-Commit-ID: 59I61PQIWHi --- layout/style/crashtests/1387499.html | 15 +++++++++++++++ layout/style/crashtests/crashtests.list | 1 + 2 files changed, 16 insertions(+) create mode 100644 layout/style/crashtests/1387499.html diff --git a/layout/style/crashtests/1387499.html b/layout/style/crashtests/1387499.html new file mode 100644 index 000000000000..86afa3e84fb4 --- /dev/null +++ b/layout/style/crashtests/1387499.html @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index eb5941b962f3..b20f85456750 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -199,3 +199,4 @@ load 1383981-2.html load 1384824-1.html load 1384824-2.html load 1387481-1.html +load 1387499.html From 2efc656d5f3350f60d772436f91b6c752065051e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Wed, 9 Aug 2017 10:19:57 -0500 Subject: [PATCH 041/166] servo: Merge #18021 - Update Trusted documentation (from ferjm:trusted.doc); r=jdm Source-Repo: https://github.com/servo/servo Source-Revision: 8074c6aaad06c11e85f6cf02404457c9b91a0092 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 59dec3d44ee512746526032815341fb654ada99e --- servo/components/script/dom/bindings/refcounted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servo/components/script/dom/bindings/refcounted.rs b/servo/components/script/dom/bindings/refcounted.rs index bbac02288fcc..8acbe823e7c1 100644 --- a/servo/components/script/dom/bindings/refcounted.rs +++ b/servo/components/script/dom/bindings/refcounted.rs @@ -11,7 +11,7 @@ //! To guarantee the lifetime of a DOM object when performing asynchronous operations, //! obtain a `Trusted` from that object and pass it along with each operation. //! A usable pointer to the original DOM object can be obtained on the script thread -//! from a `Trusted` via the `to_temporary` method. +//! from a `Trusted` via the `root` method. //! //! The implementation of `Trusted` is as follows: //! The `Trusted` object contains an atomic reference counted pointer to the Rust DOM object. From d4f6f9707287e310f5835757ffe94c76fedf72bb Mon Sep 17 00:00:00 2001 From: Luke Chang Date: Fri, 28 Jul 2017 19:08:30 +0800 Subject: [PATCH 042/166] Bug 1385216 - [Form Autofill] Avoid triggering update on fields that aren't changed after autofilling or contain concatenated street address. r=seanlee,steveck MozReview-Commit-ID: KI2ns7XDiHa --HG-- extra : rebase_source : cf7fd4b5e7f8ef89c9a37c84600a7b7a12574f72 --- .../formautofill/FormAutofillContent.jsm | 23 +---- .../formautofill/FormAutofillHandler.jsm | 38 +++++--- .../formautofill/FormAutofillParent.jsm | 8 ++ .../formautofill/ProfileStorage.jsm | 23 ++++- .../test/browser/browser_update_doorhanger.js | 46 ++++++++- .../test/unit/test_addressRecords.js | 95 +++++++++++++++++++ .../test/unit/test_onFormSubmitted.js | 6 ++ 7 files changed, 199 insertions(+), 40 deletions(-) diff --git a/browser/extensions/formautofill/FormAutofillContent.jsm b/browser/extensions/formautofill/FormAutofillContent.jsm index a68f7e692349..afd3b61724e9 100644 --- a/browser/extensions/formautofill/FormAutofillContent.jsm +++ b/browser/extensions/formautofill/FormAutofillContent.jsm @@ -385,29 +385,12 @@ var FormAutofillContent = { return true; } - let {addressRecord, creditCardRecord} = handler.createRecords(); - - if (!addressRecord && !creditCardRecord) { + let records = handler.createRecords(); + if (!Object.keys(records).length) { return true; } - let data = {}; - if (addressRecord) { - data.address = { - guid: handler.address.filledRecordGUID, - record: addressRecord, - }; - } - - if (creditCardRecord) { - data.creditCard = { - guid: handler.creditCard.filledRecordGUID, - record: creditCardRecord, - }; - } - - this._onFormSubmit(data, domWin); - + this._onFormSubmit(records, domWin); return true; }, diff --git a/browser/extensions/formautofill/FormAutofillHandler.jsm b/browser/extensions/formautofill/FormAutofillHandler.jsm index 11dfc4e1dc52..2f0970ad9d42 100644 --- a/browser/extensions/formautofill/FormAutofillHandler.jsm +++ b/browser/extensions/formautofill/FormAutofillHandler.jsm @@ -451,10 +451,16 @@ FormAutofillHandler.prototype = { * Return the records that is converted from address/creditCard fieldDetails and * only valid form records are included. * - * @returns {Object} The new profile that convert from details with trimmed result. + * @returns {Object} + * Consists of two record objects: address, creditCard. Each one can + * be omitted if there's no valid fields. A record object consists of + * three properties: + * - guid: The id of the previously-filled profile or null if omitted. + * - record: A valid record converted from details with trimmed result. + * - untouchedFields: Fields that aren't touched after autofilling. */ createRecords() { - let records = {}; + let data = {}; ["address", "creditCard"].forEach(type => { let details = this[type].fieldDetails; @@ -462,8 +468,12 @@ FormAutofillHandler.prototype = { return; } - let recordName = `${type}Record`; - records[recordName] = {}; + data[type] = { + guid: this[type].filledRecordGUID, + record: {}, + untouchedFields: [], + }; + details.forEach(detail => { let element = detail.elementWeakRef.get(); // Remove the unnecessary spaces @@ -472,23 +482,27 @@ FormAutofillHandler.prototype = { return; } - records[recordName][detail.fieldName] = value; + data[type].record[detail.fieldName] = value; + + if (detail.state == "AUTO_FILLED") { + data[type].untouchedFields.push(detail.fieldName); + } }); }); - if (records.addressRecord && - Object.keys(records.addressRecord).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) { + if (data.address && + Object.keys(data.address.record).length < FormAutofillUtils.AUTOFILL_FIELDS_THRESHOLD) { log.debug("No address record saving since there are only", - Object.keys(records.addressRecord).length, + Object.keys(data.address.record).length, "usable fields"); - delete records.addressRecord; + delete data.address; } - if (records.creditCardRecord && !records.creditCardRecord["cc-number"]) { + if (data.creditCard && !data.creditCard.record["cc-number"]) { log.debug("No credit card record saving since card number is empty"); - delete records.creditCardRecord; + delete data.creditCard; } - return records; + return data; }, }; diff --git a/browser/extensions/formautofill/FormAutofillParent.jsm b/browser/extensions/formautofill/FormAutofillParent.jsm index 433f42cd1060..22b827274aee 100644 --- a/browser/extensions/formautofill/FormAutofillParent.jsm +++ b/browser/extensions/formautofill/FormAutofillParent.jsm @@ -286,6 +286,14 @@ FormAutofillParent.prototype = { let {address} = data; if (address.guid) { + // Avoid updating the fields that users don't modify. + let originalAddress = this.profileStorage.addresses.get(address.guid); + for (let field in address.record) { + if (address.untouchedFields.includes(field) && originalAddress[field]) { + address.record[field] = originalAddress[field]; + } + } + if (!this.profileStorage.addresses.mergeIfPossible(address.guid, address.record)) { FormAutofillDoorhanger.show(target, "update").then((state) => { let changedGUIDs = this.profileStorage.addresses.mergeToStorage(address.record); diff --git a/browser/extensions/formautofill/ProfileStorage.jsm b/browser/extensions/formautofill/ProfileStorage.jsm index 51fb2ac99e60..6e43e0f510f3 100644 --- a/browser/extensions/formautofill/ProfileStorage.jsm +++ b/browser/extensions/formautofill/ProfileStorage.jsm @@ -1375,10 +1375,25 @@ class Addresses extends AutofillRecords { let hasMatchingField = false; for (let field of this.VALID_FIELDS) { - if (addressToMerge[field] !== undefined && addressFound[field] !== undefined) { - if (addressToMerge[field] != addressFound[field]) { - this.log.debug("Conflicts: field", field, "has different value."); - return false; + let existingField = addressFound[field]; + let incomingField = addressToMerge[field]; + if (incomingField !== undefined && existingField !== undefined) { + if (incomingField != existingField) { + // Treat "street-address" as mergeable if their single-line versions + // match each other. + if (field == "street-address" && + FormAutofillUtils.toOneLineAddress(existingField) == FormAutofillUtils.toOneLineAddress(incomingField)) { + // Keep the value in storage if its amount of lines is greater than + // or equal to the incoming one. + if (existingField.split("\n").length >= incomingField.split("\n").length) { + // Replace the incoming field with the one in storage so it will + // be further merged back to storage. + addressToMerge[field] = existingField; + } + } else { + this.log.debug("Conflicts: field", field, "has different value."); + return false; + } } hasMatchingField = true; } diff --git a/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js b/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js index 9539a6b20a0e..8c951d6ea422 100644 --- a/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js +++ b/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js @@ -19,7 +19,7 @@ add_task(async function test_update_address() { let form = content.document.getElementById("form"); let org = form.querySelector("#organization"); await new Promise(resolve => setTimeout(resolve, 1000)); - org.value = "Mozilla"; + org.setUserInput("Mozilla"); // Wait 1000ms before submission to make sure the input value applied await new Promise(resolve => setTimeout(resolve, 1000)); @@ -52,7 +52,7 @@ add_task(async function test_create_new_address() { let form = content.document.getElementById("form"); let tel = form.querySelector("#tel"); await new Promise(resolve => setTimeout(resolve, 1000)); - tel.value = "+1-234-567-890"; + tel.setUserInput("+1234567890"); // Wait 1000ms before submission to make sure the input value applied await new Promise(resolve => setTimeout(resolve, 1000)); @@ -66,7 +66,7 @@ add_task(async function test_create_new_address() { addresses = await getAddresses(); is(addresses.length, 2, "2 addresses in storage"); - is(addresses[1].tel, "+1-234-567-890", "Verify the tel field"); + is(addresses[1].tel, "+1234567890", "Verify the tel field"); }); add_task(async function test_create_new_address_merge() { @@ -85,7 +85,7 @@ add_task(async function test_create_new_address_merge() { await ContentTask.spawn(browser, null, async function() { let form = content.document.getElementById("form"); let tel = form.querySelector("#tel"); - tel.value = "+1 617 253 5702"; + tel.setUserInput("+16172535702"); // Wait 1000ms before submission to make sure the input value applied await new Promise(resolve => setTimeout(resolve, 1000)); @@ -100,3 +100,41 @@ add_task(async function test_create_new_address_merge() { addresses = await getAddresses(); is(addresses.length, 2, "Still 2 addresses in storage"); }); + +add_task(async function test_submit_untouched_fields() { + let addresses = await getAddresses(); + is(addresses.length, 2, "2 addresses in storage"); + + await BrowserTestUtils.withNewTab({gBrowser, url: FORM_URL}, + async function(browser) { + let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel, + "popupshown"); + await openPopupOn(browser, "form #organization"); + await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser); + await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, browser); + + await ContentTask.spawn(browser, null, async function() { + let form = content.document.getElementById("form"); + let org = form.querySelector("#organization"); + await new Promise(resolve => setTimeout(resolve, 1000)); + org.setUserInput("Organization"); + + let tel = form.querySelector("#tel"); + await new Promise(resolve => setTimeout(resolve, 1000)); + tel.value = "12345"; // ".value" won't change the highlight status. + + // Wait 1000ms before submission to make sure the input value applied + await new Promise(resolve => setTimeout(resolve, 1000)); + form.querySelector("input[type=submit]").click(); + }); + + await promiseShown; + await clickDoorhangerButton(MAIN_BUTTON_INDEX); + } + ); + + addresses = await getAddresses(); + is(addresses.length, 2, "Still 2 addresses in storage"); + is(addresses[0].organization, "Organization", "organization should change"); + is(addresses[0].tel, "+16172535702", "tel should remain unchanged"); +}); diff --git a/browser/extensions/formautofill/test/unit/test_addressRecords.js b/browser/extensions/formautofill/test/unit/test_addressRecords.js index 691d048b5500..4d43514e68e7 100644 --- a/browser/extensions/formautofill/test/unit/test_addressRecords.js +++ b/browser/extensions/formautofill/test/unit/test_addressRecords.js @@ -102,6 +102,101 @@ const MERGE_TESTCASES = [ country: "US", }, }, + { + description: "Merge an address with multi-line street-address in storage and single-line incoming one", + addressInStorage: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2", + "tel": "+16509030800", + }, + addressToMerge: { + "street-address": "331 E. Evelyn Avenue Line2", + "tel": "+16509030800", + country: "US", + }, + expectedAddress: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2", + "tel": "+16509030800", + country: "US", + }, + }, + { + description: "Merge an address with 3-line street-address in storage and 2-line incoming one", + addressInStorage: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + }, + addressToMerge: { + "street-address": "331 E. Evelyn Avenue\nLine2 Line3", + "tel": "+16509030800", + country: "US", + }, + expectedAddress: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + country: "US", + }, + }, + { + description: "Merge an address with single-line street-address in storage and multi-line incoming one", + addressInStorage: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue Line2", + "tel": "+16509030800", + }, + addressToMerge: { + "street-address": "331 E. Evelyn Avenue\nLine2", + "tel": "+16509030800", + country: "US", + }, + expectedAddress: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2", + "tel": "+16509030800", + country: "US", + }, + }, + { + description: "Merge an address with 2-line street-address in storage and 3-line incoming one", + addressInStorage: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2 Line3", + "tel": "+16509030800", + }, + addressToMerge: { + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + country: "US", + }, + expectedAddress: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + country: "US", + }, + }, + { + description: "Merge an address with the same amount of lines", + addressInStorage: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + }, + addressToMerge: { + "street-address": "331 E. Evelyn\nAvenue Line2\nLine3", + "tel": "+16509030800", + country: "US", + }, + expectedAddress: { + "given-name": "Timothy", + "street-address": "331 E. Evelyn Avenue\nLine2\nLine3", + "tel": "+16509030800", + country: "US", + }, + }, ]; let do_check_record_matches = (recordWithMeta, record) => { diff --git a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js index be44393d2093..761eac373306 100644 --- a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js +++ b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js @@ -56,6 +56,7 @@ const TESTCASES = [ "country": "USA", "tel": "1-650-903-0800", }, + untouchedFields: [], }, }, }, @@ -79,6 +80,7 @@ const TESTCASES = [ "cc-exp-month": 12, "cc-exp-year": 2000, }, + untouchedFields: [], }, }, }, @@ -104,6 +106,7 @@ const TESTCASES = [ "country": "USA", "tel": "1-650-903-0800", }, + untouchedFields: [], }, creditCard: { guid: null, @@ -113,6 +116,7 @@ const TESTCASES = [ "cc-exp-month": 12, "cc-exp-year": 2000, }, + untouchedFields: [], }, }, }, @@ -134,6 +138,7 @@ const TESTCASES = [ "country": "USA", "tel": "1-650-903-0800", }, + untouchedFields: [], }, }, }, @@ -156,6 +161,7 @@ const TESTCASES = [ "country": "USA", "tel": "1-650-903-0800", }, + untouchedFields: [], }, }, }, From 6883d3efda3bff9fe7e996ebb2b267a76fc3806f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Wed, 9 Aug 2017 10:30:14 +0200 Subject: [PATCH 043/166] Bug 1377184 - Consistently use the custom toolbar button styling in all browser toolbars. r=johannh MozReview-Commit-ID: Czp2oURcztE --HG-- extra : rebase_source : c5383d50402a1d2161334278261e785c348cfd9a --- browser/base/content/browser.xul | 2 +- .../performance/browser_startup_images.js | 10 +--- browser/themes/linux/browser.css | 22 -------- browser/themes/osx/browser.css | 36 ------------ browser/themes/shared/tabs.inc.css | 5 -- .../themes/shared/toolbarbutton-icons.inc.css | 1 + browser/themes/shared/toolbarbuttons.inc.css | 52 ++++++++---------- browser/themes/windows/browser.css | 22 -------- .../osx/global/icons/chevron-inverted.png | Bin 247 -> 0 bytes .../osx/global/icons/chevron-inverted@2x.png | Bin 481 -> 0 bytes toolkit/themes/osx/global/icons/chevron.png | Bin 251 -> 0 bytes .../themes/osx/global/icons/chevron@2x.png | Bin 462 -> 0 bytes toolkit/themes/osx/global/jar.mn | 4 -- toolkit/themes/shared/non-mac.jar.inc.mn | 2 - .../global/toolbar/chevron-inverted.png | Bin 85 -> 0 bytes .../themes/windows/global/toolbar/chevron.gif | Bin 57 -> 0 bytes 16 files changed, 28 insertions(+), 128 deletions(-) delete mode 100644 toolkit/themes/osx/global/icons/chevron-inverted.png delete mode 100644 toolkit/themes/osx/global/icons/chevron-inverted@2x.png delete mode 100644 toolkit/themes/osx/global/icons/chevron.png delete mode 100644 toolkit/themes/osx/global/icons/chevron@2x.png delete mode 100644 toolkit/themes/windows/global/toolbar/chevron-inverted.png delete mode 100644 toolkit/themes/windows/global/toolbar/chevron.gif diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index c1db021ffc0c..4e50030faa7b 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -1116,7 +1116,7 @@ flex="1"/> .toolbarbutton-icon { - transform: scaleX(-1); -} - -toolbarbutton.chevron > .toolbarbutton-text, -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - -toolbarbutton.chevron > .toolbarbutton-icon { - margin: 0; -} - /* Status panel */ .statuspanel-label { diff --git a/browser/themes/osx/browser.css b/browser/themes/osx/browser.css index afab1f427593..d38bd925f513 100644 --- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -195,38 +195,6 @@ -moz-box-align: center; } -toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron.png"); - margin: 1px 0 0; - padding: 0; -} - -toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron-inverted.png"); -} - -toolbarbutton.chevron > .toolbarbutton-text { - display: none; -} - -toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { - transform: scaleX(-1); -} - -@media (min-resolution: 2dppx) { - toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron@2x.png"); - } - - toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron-inverted@2x.png"); - } - - toolbarbutton.chevron > .toolbarbutton-icon { - width: 13px; - } -} - /* ----- BOOKMARK BUTTONS ----- */ .bookmark-item[container] { @@ -1072,10 +1040,6 @@ html|span.ac-emphasize-text-url { text-shadow: none; } -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - .bookmark-item { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg"); } diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index de83e90cbb6e..2dc39d514952 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -443,9 +443,6 @@ #TabsToolbar > #new-tab-button , #TabsToolbar > toolbarpaletteitem > #new-tab-button { list-style-image: url(chrome://browser/skin/tabbrowser/newtab.svg); - -moz-context-properties: fill; - fill: currentColor; - color: inherit; } .tabs-newtab-button { @@ -466,8 +463,6 @@ #alltabs-button { list-style-image: url(chrome://browser/skin/arrow-dropdown-16.svg); - -moz-context-properties: fill; - fill: currentColor; } .alltabs-item > .menu-iconic-left > .menu-iconic-icon { diff --git a/browser/themes/shared/toolbarbutton-icons.inc.css b/browser/themes/shared/toolbarbutton-icons.inc.css index 3349d31ae39e..80526d6265a9 100644 --- a/browser/themes/shared/toolbarbutton-icons.inc.css +++ b/browser/themes/shared/toolbarbutton-icons.inc.css @@ -300,6 +300,7 @@ toolbar:not([brighttext]) #bookmarks-menu-button[starred] > .toolbarbutton-menub list-style-image: url("chrome://browser/skin/zoom-in.svg"); } +#PlacesChevron, #nav-bar-overflow-button { list-style-image: url("chrome://browser/skin/chevron.svg"); } diff --git a/browser/themes/shared/toolbarbuttons.inc.css b/browser/themes/shared/toolbarbuttons.inc.css index e9055f24bbd7..52692b3cba7a 100644 --- a/browser/themes/shared/toolbarbuttons.inc.css +++ b/browser/themes/shared/toolbarbuttons.inc.css @@ -11,8 +11,8 @@ --backbutton-background: hsla(0,100%,100%,.8); --backbutton-hover-background: var(--backbutton-background); --backbutton-active-background: var(--toolbarbutton-active-background); - --backbutton-border-color: hsla(240,5%,5%,.3); + /* This default value of --toolbarbutton-height is defined to prevent CSS errors for an invalid variable. The value should not get used, as a more specific value should be set when the value will be used. */ @@ -49,8 +49,8 @@ toolbar[brighttext] { margin-inline-end: 0; } -:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-icon, -:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { +.toolbarbutton-1 > .toolbarbutton-icon, +.toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { max-width: 16px; } @@ -60,7 +60,6 @@ toolbar[brighttext] { margin: 0 0 var(--tab-toolbar-navbar-overlap); } -#TabsToolbar .toolbarbutton-1, .tabbrowser-arrowscrollbox > .scrollbutton-up, .tabbrowser-arrowscrollbox > .scrollbutton-down { -moz-appearance: none; @@ -89,49 +88,48 @@ toolbar[brighttext] { padding: 0; } -#nav-bar .toolbarbutton-1 { +toolbar .toolbarbutton-1 { -moz-appearance: none; margin: 0; padding: 0 2px; -moz-box-pack: center; } -#nav-bar #PanelUI-menu-button { +#PanelUI-menu-button { padding-inline-start: 5px; padding-inline-end: 5px; } -#nav-bar .toolbarbutton-1 > menupopup { +toolbar .toolbarbutton-1 > menupopup { margin-top: -3px; } -#nav-bar .toolbarbutton-1 > menupopup.cui-widget-panel { +toolbar .toolbarbutton-1 > menupopup.cui-widget-panel { margin-top: -8px; } .findbar-button > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton), -#nav-bar .toolbarbutton-1 > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1 > .toolbarbutton-text, -#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1 > .toolbarbutton-icon, +toolbar .toolbarbutton-1 > .toolbarbutton-text, +toolbar .toolbarbutton-1 > .toolbarbutton-badge-stack { padding: var(--toolbarbutton-inner-padding); border-radius: var(--toolbarbutton-border-radius); transition-property: background-color, border-color, box-shadow; transition-duration: 150ms; } -#nav-bar .toolbarbutton-1 > .toolbarbutton-icon { +toolbar .toolbarbutton-1 > .toolbarbutton-icon { /* horizontal padding + actual icon width */ max-width: calc(2 * var(--toolbarbutton-inner-padding) + 16px); } .bookmark-item > .toolbarbutton-menu-dropmarker, -#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker, -#nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { +toolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { display: none; } -#nav-bar .toolbarbutton-1 > .toolbarbutton-text { +toolbar .toolbarbutton-1 > .toolbarbutton-text { padding-top: var(--toolbarbutton-vertical-text-padding); padding-bottom: 0; /* To make the hover feedback line up with sibling buttons, it needs the same @@ -141,17 +139,17 @@ toolbarbutton.bookmark-item:not(.subviewbutton), min-height: calc(16px + 2 * var(--toolbarbutton-inner-padding)); } -#nav-bar .toolbaritem-combined-buttons { +toolbar .toolbaritem-combined-buttons { margin-left: 2px; margin-right: 2px; } -#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1 { +toolbar .toolbaritem-combined-buttons > .toolbarbutton-1 { padding-left: 0; padding-right: 0; } -#nav-bar .toolbaritem-combined-buttons:not(:hover) > separator { +toolbar .toolbaritem-combined-buttons:not(:hover) > separator { content: ""; display: -moz-box; width: 1px; @@ -164,19 +162,17 @@ toolbarbutton.bookmark-item:not(.subviewbutton), opacity: .2; } -#nav-bar[brighttext] .toolbaritem-combined-buttons > separator { +toolbar[brighttext] .toolbaritem-combined-buttons > separator { opacity: .3; } -#TabsToolbar .toolbarbutton-1:not([disabled=true]):hover, -#TabsToolbar .toolbarbutton-1[open], .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled=true]):hover, .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled=true]):hover, .findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not([open]), -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-hover-background); color: inherit; } @@ -184,15 +180,15 @@ toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not .findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:active:not([disabled="true"]), toolbarbutton.bookmark-item[open="true"], -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-active-background); transition-duration: 10ms; color: inherit; } -#nav-bar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { +toolbar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { background-color: var(--toolbarbutton-hover-background); transition: background-color .4s; } diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index d88bbf8c90bb..6f0ffb2ad53c 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -1045,28 +1045,6 @@ treechildren.searchbar-treebody::-moz-tree-row(selected) { font-weight: bold; } - -toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important; -} - -toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important; -} - -toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { - transform: scaleX(-1); -} - -toolbarbutton.chevron > .toolbarbutton-text, -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - -toolbarbutton.chevron > .toolbarbutton-icon { - margin: 0; -} - /* Bookmarks toolbar */ #PlacesToolbarDropIndicator { list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png); diff --git a/toolkit/themes/osx/global/icons/chevron-inverted.png b/toolkit/themes/osx/global/icons/chevron-inverted.png deleted file mode 100644 index 8ad164baaf7d205f16d7d7742d2fdd09caf71efc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmV`q2*z3^2a)7uFo>%F3Vi(k&DK4(62e+2 z4U%MH;A1e%to#4||GWQRjNLNoA*|WrAbm^>0_`dP-~NB||GlGmTPlPVsR5QcVe|jP z|JVQDm?lmLhO!bEWPlRK%z#F`{QufEr#uS6vdd=BVc=pos0+0A)&Eysh3O#>mUjVz xE(15n8Db2!43P{$35OBIAEnFF&nX$tVSE;Hp7%VWBOoCR1#t%jAv$|G;T4=~Y`JFe3P&J$IU&NS zuXP$14omYLT?u(OiI1|ox7!^yV^dBJeq-Nr@t>&dBOR)bAwGKtZ99d~gpdSRpq z?lP41W0%6oag*6J8-)2mM;U4$Z?yzhaQ`VOk}zxT-1tayF_1Uvg1dtFI+6Ds9lWO5 zWJALE)CDDb@;}~ij!S^xeDzzbf1g-w@1hy$sU|os0rulGwot}HJVFJxaFymmqT`dl Xk4DNQT~lE;00000NkvXXu0mjfX1>!~ diff --git a/toolkit/themes/osx/global/icons/chevron.png b/toolkit/themes/osx/global/icons/chevron.png deleted file mode 100644 index b2d31e38f56dda9807001c84e1d2bc31ced0eb0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(0wkS_^Bw{z$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gb3I)gLpY+769m#DP8#$lDmE(!aWnnnj?GQcNI#J_!_JZK zSki-L&#st^6pbX0)ERpM_)ciCY+7dU;eg6f|7*r7MlMD^_q6zv4GWx9jn7Cdl4z1B z(qa+R>FCjM)@_z|{`0y@Hq}7;Vd>v`z6mWV&Z^DU&PP65rK`4aalE!S_i$=i*sM53 v@t0$66I0LE`TVbb{O3*3Xi0F)VPtr}*M4EaiEoTRhcbA&`njxgN@xNAvglRU diff --git a/toolkit/themes/osx/global/icons/chevron@2x.png b/toolkit/themes/osx/global/icons/chevron@2x.png deleted file mode 100644 index dd91178030e5f6b315f642909617cce898cdfb7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)$^ zOG`pg6opriQi44uc1tt8r9@FC5s@kOen~Hiuqb=bLo32bl9XV9^iU%L8y7U{r!?ya z)TBw1AP8#EV7GO2@AaI;oqT((v-dgN1JY3yNmN^qM3qzuh?r`Tq2dltc)&gD(VStM zPQ=t99o1T{kV6J({&G^5E#(5H?nd&Tw=IEvY_OupSiM4+Fo8#EVB7)dLw(f!latWC7Y*a!`9|MjU zLYQZ*BP}P{(pqX!qk6=$w_$8zvY=@kJ;WM z&I(}37bO=Nideg1Jkr0|O=md92!=6=g^nnBNEWbq#eeZ?H6^(`fqo2P)_p*|Bny~T z5&5)m`H0It_%Y?$CoegQSTEUB5px1D9>4=H0$mXDzK%yXd1|}{SmA1+~uNF*N%fMg_ E0ON=ds{jB1 From 357b81bcfdc4e30963cbc56206ea6233a09f6238 Mon Sep 17 00:00:00 2001 From: Thomas Wisniewski Date: Tue, 8 Aug 2017 22:55:43 -0400 Subject: [PATCH 044/166] Bug 1388591 - Implement OfflineAudioCanvas dict constructor; r=padenot,smaug MozReview-Commit-ID: F9h9JO5tYeU --HG-- extra : rebase_source : 111cb0d4a574cce4d5c8869e5953dfbb68d01e72 --- dom/media/webaudio/AudioContext.cpp | 12 +++++++ dom/media/webaudio/AudioContext.h | 7 ++++ .../test/test_OfflineAudioContext.html | 34 +++++++++++++++---- dom/webidl/OfflineAudioContext.webidl | 9 ++++- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp index 085430a9ef92..81e6ef2e824f 100644 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -219,6 +219,18 @@ AudioContext::Constructor(const GlobalObject& aGlobal, return object.forget(); } +/* static */ already_AddRefed +AudioContext::Constructor(const GlobalObject& aGlobal, + const OfflineAudioContextOptions& aOptions, + ErrorResult& aRv) +{ + return Constructor(aGlobal, + aOptions.mNumberOfChannels, + aOptions.mLength, + aOptions.mSampleRate, + aRv); +} + /* static */ already_AddRefed AudioContext::Constructor(const GlobalObject& aGlobal, uint32_t aNumberOfChannels, diff --git a/dom/media/webaudio/AudioContext.h b/dom/media/webaudio/AudioContext.h index b1c43fa1e0cf..683cd3fe4857 100644 --- a/dom/media/webaudio/AudioContext.h +++ b/dom/media/webaudio/AudioContext.h @@ -8,6 +8,7 @@ #define AudioContext_h_ #include "mozilla/dom/AudioChannelBinding.h" +#include "mozilla/dom/OfflineAudioContextBinding.h" #include "MediaBufferDecoder.h" #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" @@ -154,6 +155,12 @@ public: static already_AddRefed Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); + // Constructor for offline AudioContext with options object + static already_AddRefed + Constructor(const GlobalObject& aGlobal, + const OfflineAudioContextOptions& aOptions, + ErrorResult& aRv); + // Constructor for offline AudioContext static already_AddRefed Constructor(const GlobalObject& aGlobal, diff --git a/dom/media/webaudio/test/test_OfflineAudioContext.html b/dom/media/webaudio/test/test_OfflineAudioContext.html index ae4a4bb2db0f..07397ffe3e37 100644 --- a/dom/media/webaudio/test/test_OfflineAudioContext.html +++ b/dom/media/webaudio/test/test_OfflineAudioContext.html @@ -31,17 +31,28 @@ function setOrCompareRenderedBuffer(aRenderedBuffer) { SimpleTest.waitForExplicitFinish(); addLoadEvent(function() { - var ctx = new OfflineAudioContext(2, 100, 22050); - ok(ctx instanceof EventTarget, "OfflineAudioContexts must be EventTargets"); - is(ctx.length, 100, "OfflineAudioContext.length is equal to the value passed to the ctor."); + let ctxs = [ + new OfflineAudioContext(2, 100, 22050), + new OfflineAudioContext({length: 100, sampleRate: 22050}), + new OfflineAudioContext({channels: 2, length: 100, sampleRate: 22050}), + ]; - var buf = ctx.createBuffer(2, 100, ctx.sampleRate); - for (var i = 0; i < 2; ++i) { - for (var j = 0; j < 100; ++j) { - buf.getChannelData(i)[j] = Math.sin(2 * Math.PI * 200 * j / ctx.sampleRate); + for (let ctx of ctxs) { + ok(ctx instanceof EventTarget, "OfflineAudioContexts must be EventTargets"); + is(ctx.length, 100, "OfflineAudioContext.length is equal to the value passed to the ctor."); + + var buf = ctx.createBuffer(2, 100, ctx.sampleRate); + for (var i = 0; i < 2; ++i) { + for (var j = 0; j < 100; ++j) { + buf.getChannelData(i)[j] = Math.sin(2 * Math.PI * 200 * j / ctx.sampleRate); + } } } + is(ctxs[1].destination.channelCount, 1, "OfflineAudioContext defaults to to correct channelCount."); + + let ctx = ctxs[0]; + expectException(function() { new OfflineAudioContext(2, 100, 0); }, DOMException.NOT_SUPPORTED_ERR); @@ -58,6 +69,15 @@ addLoadEvent(function() { expectException(function() { new OfflineAudioContext(2, 0, 44100); }, DOMException.NOT_SUPPORTED_ERR); + expectTypeError(function() { + new OfflineAudioContext({}); + }); + expectTypeError(function() { + new OfflineAudioContext({sampleRate: 44100}); + }); + expectTypeError(function() { + new OfflineAudioContext({length: 44100*40}); + }); var src = ctx.createBufferSource(); src.buffer = buf; diff --git a/dom/webidl/OfflineAudioContext.webidl b/dom/webidl/OfflineAudioContext.webidl index 262fcac8e0fb..a2498d6e56a8 100644 --- a/dom/webidl/OfflineAudioContext.webidl +++ b/dom/webidl/OfflineAudioContext.webidl @@ -10,7 +10,14 @@ * liability, trademark and document use rules apply. */ -[Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate), +dictionary OfflineAudioContextOptions { + unsigned long numberOfChannels = 1; + required unsigned long length; + required float sampleRate; +}; + +[Constructor (OfflineAudioContextOptions contextOptions), +Constructor(unsigned long numberOfChannels, unsigned long length, float sampleRate), Pref="dom.webaudio.enabled"] interface OfflineAudioContext : BaseAudioContext { From 085bdaee0bef90dcaa5a8d053183abde7ef5def4 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 11:17:49 -0400 Subject: [PATCH 045/166] Bug 1388726 - Fix the pref used to disable acceleration in linux reftest-unaccelerated runs. r=jmaher MozReview-Commit-ID: HaYzi1x87q1 --HG-- extra : rebase_source : f88d21508d69e68820e5856189a422d1388a25b1 --- testing/mozharness/configs/unittests/linux_unittest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mozharness/configs/unittests/linux_unittest.py b/testing/mozharness/configs/unittests/linux_unittest.py index 51bd09a658a9..c8d33851c704 100644 --- a/testing/mozharness/configs/unittests/linux_unittest.py +++ b/testing/mozharness/configs/unittests/linux_unittest.py @@ -227,7 +227,7 @@ config = { }, "reftest-no-accel": { "options": ["--suite=reftest", - "--setpref=layers.acceleration.force-enabled=disabled"], + "--setpref=layers.acceleration.disabled=true"], "tests": ["tests/reftest/tests/layout/reftests/reftest.list"] }, "reftest-stylo": { From 1912af35f9a3a5cf4e0d9eaf927bfbe028d03bf5 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 12:48:08 -0400 Subject: [PATCH 046/166] Bug 1388726 - Force-enable acceleration in the regular linux reftest suite. r=jmaher,jrmuizel MozReview-Commit-ID: FNU7hEN3Jkf --HG-- extra : rebase_source : d8f21f99a3d98904a9b3d4b402226c0c58519b63 --- dom/media/test/reftest/reftest.list | 6 +++--- testing/mozharness/configs/unittests/linux_unittest.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dom/media/test/reftest/reftest.list b/dom/media/test/reftest/reftest.list index c551ce964d3f..77954a46e60f 100644 --- a/dom/media/test/reftest/reftest.list +++ b/dom/media/test/reftest/reftest.list @@ -1,3 +1,3 @@ -skip-if(Android) fuzzy-if(OSX,22,49977) skip-if(winWidget) fuzzy-if(webrender,70,600) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html -skip-if(Android) fuzzy-if(OSX,23,51392) fuzzy-if(winWidget,59,76797) fuzzy-if(webrender,60,1800) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html -skip-if(Android) skip-if(winWidget) fuzzy-if(webrender,55,4281) fuzzy-if(OSX,3,111852) HTTP(..) == bipbop_300_215kbps.mp4.lastframe.html bipbop_300_215kbps.mp4.lastframe-ref.html \ No newline at end of file +skip-if(Android) fuzzy-if(OSX,22,49977) skip-if(winWidget) fuzzy-if(gtkWidget&&layersGPUAccelerated,70,600) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html +skip-if(Android) fuzzy-if(OSX,23,51392) fuzzy-if(winWidget,59,76797) fuzzy-if(gtkWidget&&layersGPUAccelerated,60,1800) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html +skip-if(Android) skip-if(winWidget) fuzzy-if(gtkWidget&&layersGPUAccelerated,55,4281) fuzzy-if(OSX,3,111852) HTTP(..) == bipbop_300_215kbps.mp4.lastframe.html bipbop_300_215kbps.mp4.lastframe-ref.html diff --git a/testing/mozharness/configs/unittests/linux_unittest.py b/testing/mozharness/configs/unittests/linux_unittest.py index c8d33851c704..eeee3d279d60 100644 --- a/testing/mozharness/configs/unittests/linux_unittest.py +++ b/testing/mozharness/configs/unittests/linux_unittest.py @@ -222,7 +222,8 @@ config = { "tests": ["tests/jsreftest/tests/jstests.list"] }, "reftest": { - "options": ["--suite=reftest"], + "options": ["--suite=reftest", + "--setpref=layers.acceleration.force-enabled=true"], "tests": ["tests/reftest/tests/layout/reftests/reftest.list"] }, "reftest-no-accel": { From 826714b0ab354c305817a17001dc435437a80fe0 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 9 Aug 2017 19:43:23 +0200 Subject: [PATCH 047/166] Backed out changeset 1a3018f82800 (bug 1376511) for failing browser-chrome's browser_thumbnails_bug726727.js and browser_thumbnails_bug818225.js. r=backout --- toolkit/content/browser-child.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 5893b253d310..50880cfd0ea6 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -559,11 +559,9 @@ addMessageListener("Browser:Thumbnail:Request", function(aMessage) { * Remote isSafeForCapture request handler for PageThumbs. */ addMessageListener("Browser:Thumbnail:CheckState", function(aMessage) { - requestIdleCallback(() => { - let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); - sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { - result - }); + let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); + sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { + result }); }); From e99c254eb98b7b839cf3b534fb4d55e3ae77c1ce Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 9 Aug 2017 19:51:01 +0200 Subject: [PATCH 048/166] Backed out changeset c4376773f9cd (bug 1377184) for failing browser-chrome's browser_startup_images.js: chevron.svg should have been shown. r=backout --- browser/base/content/browser.xul | 2 +- .../performance/browser_startup_images.js | 10 +++- browser/themes/linux/browser.css | 22 ++++++++ browser/themes/osx/browser.css | 36 ++++++++++++ browser/themes/shared/tabs.inc.css | 5 ++ .../themes/shared/toolbarbutton-icons.inc.css | 1 - browser/themes/shared/toolbarbuttons.inc.css | 52 ++++++++++-------- browser/themes/windows/browser.css | 22 ++++++++ .../osx/global/icons/chevron-inverted.png | Bin 0 -> 247 bytes .../osx/global/icons/chevron-inverted@2x.png | Bin 0 -> 481 bytes toolkit/themes/osx/global/icons/chevron.png | Bin 0 -> 251 bytes .../themes/osx/global/icons/chevron@2x.png | Bin 0 -> 462 bytes toolkit/themes/osx/global/jar.mn | 4 ++ toolkit/themes/shared/non-mac.jar.inc.mn | 2 + .../global/toolbar/chevron-inverted.png | Bin 0 -> 85 bytes .../themes/windows/global/toolbar/chevron.gif | Bin 0 -> 57 bytes 16 files changed, 128 insertions(+), 28 deletions(-) create mode 100644 toolkit/themes/osx/global/icons/chevron-inverted.png create mode 100644 toolkit/themes/osx/global/icons/chevron-inverted@2x.png create mode 100644 toolkit/themes/osx/global/icons/chevron.png create mode 100644 toolkit/themes/osx/global/icons/chevron@2x.png create mode 100644 toolkit/themes/windows/global/toolbar/chevron-inverted.png create mode 100644 toolkit/themes/windows/global/toolbar/chevron.gif diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 4e50030faa7b..c1db021ffc0c 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -1116,7 +1116,7 @@ flex="1"/> .toolbarbutton-icon { + transform: scaleX(-1); +} + +toolbarbutton.chevron > .toolbarbutton-text, +toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { + display: none; +} + +toolbarbutton.chevron > .toolbarbutton-icon { + margin: 0; +} + /* Status panel */ .statuspanel-label { diff --git a/browser/themes/osx/browser.css b/browser/themes/osx/browser.css index d38bd925f513..afab1f427593 100644 --- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -195,6 +195,38 @@ -moz-box-align: center; } +toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/icons/chevron.png"); + margin: 1px 0 0; + padding: 0; +} + +toolbar[brighttext] toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/icons/chevron-inverted.png"); +} + +toolbarbutton.chevron > .toolbarbutton-text { + display: none; +} + +toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { + transform: scaleX(-1); +} + +@media (min-resolution: 2dppx) { + toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/icons/chevron@2x.png"); + } + + toolbar[brighttext] toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/icons/chevron-inverted@2x.png"); + } + + toolbarbutton.chevron > .toolbarbutton-icon { + width: 13px; + } +} + /* ----- BOOKMARK BUTTONS ----- */ .bookmark-item[container] { @@ -1040,6 +1072,10 @@ html|span.ac-emphasize-text-url { text-shadow: none; } +toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { + display: none; +} + .bookmark-item { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg"); } diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index 2dc39d514952..de83e90cbb6e 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -443,6 +443,9 @@ #TabsToolbar > #new-tab-button , #TabsToolbar > toolbarpaletteitem > #new-tab-button { list-style-image: url(chrome://browser/skin/tabbrowser/newtab.svg); + -moz-context-properties: fill; + fill: currentColor; + color: inherit; } .tabs-newtab-button { @@ -463,6 +466,8 @@ #alltabs-button { list-style-image: url(chrome://browser/skin/arrow-dropdown-16.svg); + -moz-context-properties: fill; + fill: currentColor; } .alltabs-item > .menu-iconic-left > .menu-iconic-icon { diff --git a/browser/themes/shared/toolbarbutton-icons.inc.css b/browser/themes/shared/toolbarbutton-icons.inc.css index 80526d6265a9..3349d31ae39e 100644 --- a/browser/themes/shared/toolbarbutton-icons.inc.css +++ b/browser/themes/shared/toolbarbutton-icons.inc.css @@ -300,7 +300,6 @@ toolbar:not([brighttext]) #bookmarks-menu-button[starred] > .toolbarbutton-menub list-style-image: url("chrome://browser/skin/zoom-in.svg"); } -#PlacesChevron, #nav-bar-overflow-button { list-style-image: url("chrome://browser/skin/chevron.svg"); } diff --git a/browser/themes/shared/toolbarbuttons.inc.css b/browser/themes/shared/toolbarbuttons.inc.css index 52692b3cba7a..e9055f24bbd7 100644 --- a/browser/themes/shared/toolbarbuttons.inc.css +++ b/browser/themes/shared/toolbarbuttons.inc.css @@ -11,8 +11,8 @@ --backbutton-background: hsla(0,100%,100%,.8); --backbutton-hover-background: var(--backbutton-background); --backbutton-active-background: var(--toolbarbutton-active-background); - --backbutton-border-color: hsla(240,5%,5%,.3); + --backbutton-border-color: hsla(240,5%,5%,.3); /* This default value of --toolbarbutton-height is defined to prevent CSS errors for an invalid variable. The value should not get used, as a more specific value should be set when the value will be used. */ @@ -49,8 +49,8 @@ toolbar[brighttext] { margin-inline-end: 0; } -.toolbarbutton-1 > .toolbarbutton-icon, -.toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { +:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-icon, +:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { max-width: 16px; } @@ -60,6 +60,7 @@ toolbar[brighttext] { margin: 0 0 var(--tab-toolbar-navbar-overlap); } +#TabsToolbar .toolbarbutton-1, .tabbrowser-arrowscrollbox > .scrollbutton-up, .tabbrowser-arrowscrollbox > .scrollbutton-down { -moz-appearance: none; @@ -88,48 +89,49 @@ toolbar[brighttext] { padding: 0; } -toolbar .toolbarbutton-1 { +#nav-bar .toolbarbutton-1 { -moz-appearance: none; margin: 0; padding: 0 2px; -moz-box-pack: center; } -#PanelUI-menu-button { +#nav-bar #PanelUI-menu-button { padding-inline-start: 5px; padding-inline-end: 5px; } -toolbar .toolbarbutton-1 > menupopup { +#nav-bar .toolbarbutton-1 > menupopup { margin-top: -3px; } -toolbar .toolbarbutton-1 > menupopup.cui-widget-panel { +#nav-bar .toolbarbutton-1 > menupopup.cui-widget-panel { margin-top: -8px; } .findbar-button > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton), -toolbar .toolbarbutton-1 > .toolbarbutton-icon, -toolbar .toolbarbutton-1 > .toolbarbutton-text, -toolbar .toolbarbutton-1 > .toolbarbutton-badge-stack { +#nav-bar .toolbarbutton-1 > .toolbarbutton-icon, +#nav-bar .toolbarbutton-1 > .toolbarbutton-text, +#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack { padding: var(--toolbarbutton-inner-padding); border-radius: var(--toolbarbutton-border-radius); transition-property: background-color, border-color, box-shadow; transition-duration: 150ms; } -toolbar .toolbarbutton-1 > .toolbarbutton-icon { +#nav-bar .toolbarbutton-1 > .toolbarbutton-icon { /* horizontal padding + actual icon width */ max-width: calc(2 * var(--toolbarbutton-inner-padding) + 16px); } .bookmark-item > .toolbarbutton-menu-dropmarker, -toolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { +#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker, +#nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { display: none; } -toolbar .toolbarbutton-1 > .toolbarbutton-text { +#nav-bar .toolbarbutton-1 > .toolbarbutton-text { padding-top: var(--toolbarbutton-vertical-text-padding); padding-bottom: 0; /* To make the hover feedback line up with sibling buttons, it needs the same @@ -139,17 +141,17 @@ toolbar .toolbarbutton-1 > .toolbarbutton-text { min-height: calc(16px + 2 * var(--toolbarbutton-inner-padding)); } -toolbar .toolbaritem-combined-buttons { +#nav-bar .toolbaritem-combined-buttons { margin-left: 2px; margin-right: 2px; } -toolbar .toolbaritem-combined-buttons > .toolbarbutton-1 { +#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1 { padding-left: 0; padding-right: 0; } -toolbar .toolbaritem-combined-buttons:not(:hover) > separator { +#nav-bar .toolbaritem-combined-buttons:not(:hover) > separator { content: ""; display: -moz-box; width: 1px; @@ -162,17 +164,19 @@ toolbar .toolbaritem-combined-buttons:not(:hover) > separator { opacity: .2; } -toolbar[brighttext] .toolbaritem-combined-buttons > separator { +#nav-bar[brighttext] .toolbaritem-combined-buttons > separator { opacity: .3; } +#TabsToolbar .toolbarbutton-1:not([disabled=true]):hover, +#TabsToolbar .toolbarbutton-1[open], .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled=true]):hover, .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled=true]):hover, .findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not([open]), -toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, -toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, -toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { +#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, +#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, +#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-hover-background); color: inherit; } @@ -180,15 +184,15 @@ toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:ac .findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:active:not([disabled="true"]), toolbarbutton.bookmark-item[open="true"], -toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, -toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, -toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { +#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, +#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, +#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-active-background); transition-duration: 10ms; color: inherit; } -toolbar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { +#nav-bar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { background-color: var(--toolbarbutton-hover-background); transition: background-color .4s; } diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index 6f0ffb2ad53c..d88bbf8c90bb 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -1045,6 +1045,28 @@ treechildren.searchbar-treebody::-moz-tree-row(selected) { font-weight: bold; } + +toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important; +} + +toolbar[brighttext] toolbarbutton.chevron { + list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important; +} + +toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { + transform: scaleX(-1); +} + +toolbarbutton.chevron > .toolbarbutton-text, +toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { + display: none; +} + +toolbarbutton.chevron > .toolbarbutton-icon { + margin: 0; +} + /* Bookmarks toolbar */ #PlacesToolbarDropIndicator { list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png); diff --git a/toolkit/themes/osx/global/icons/chevron-inverted.png b/toolkit/themes/osx/global/icons/chevron-inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..8ad164baaf7d205f16d7d7742d2fdd09caf71efc GIT binary patch literal 247 zcmV`q2*z3^2a)7uFo>%F3Vi(k&DK4(62e+2 z4U%MH;A1e%to#4||GWQRjNLNoA*|WrAbm^>0_`dP-~NB||GlGmTPlPVsR5QcVe|jP z|JVQDm?lmLhO!bEWPlRK%z#F`{QufEr#uS6vdd=BVc=pos0+0A)&Eysh3O#>mUjVz xE(15n8Db2!43P{$35OBIAEnFF&nX$tVSE;Hp7%VWBOoCR1#t%jAv$|G;T4=~Y`JFe3P&J$IU&NS zuXP$14omYLT?u(OiI1|ox7!^yV^dBJeq-Nr@t>&dBOR)bAwGKtZ99d~gpdSRpq z?lP41W0%6oag*6J8-)2mM;U4$Z?yzhaQ`VOk}zxT-1tayF_1Uvg1dtFI+6Ds9lWO5 zWJALE)CDDb@;}~ij!S^xeDzzbf1g-w@1hy$sU|os0rulGwot}HJVFJxaFymmqT`dl Xk4DNQT~lE;00000NkvXXu0mjfX1>!~ literal 0 HcmV?d00001 diff --git a/toolkit/themes/osx/global/icons/chevron.png b/toolkit/themes/osx/global/icons/chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..b2d31e38f56dda9807001c84e1d2bc31ced0eb0e GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(0wkS_^Bw{z$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gb3I)gLpY+769m#DP8#$lDmE(!aWnnnj?GQcNI#J_!_JZK zSki-L&#st^6pbX0)ERpM_)ciCY+7dU;eg6f|7*r7MlMD^_q6zv4GWx9jn7Cdl4z1B z(qa+R>FCjM)@_z|{`0y@Hq}7;Vd>v`z6mWV&Z^DU&PP65rK`4aalE!S_i$=i*sM53 v@t0$66I0LE`TVbb{O3*3Xi0F)VPtr}*M4EaiEoTRhcbA&`njxgN@xNAvglRU literal 0 HcmV?d00001 diff --git a/toolkit/themes/osx/global/icons/chevron@2x.png b/toolkit/themes/osx/global/icons/chevron@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..dd91178030e5f6b315f642909617cce898cdfb7d GIT binary patch literal 462 zcmV;<0WtoGP)$^ zOG`pg6opriQi44uc1tt8r9@FC5s@kOen~Hiuqb=bLo32bl9XV9^iU%L8y7U{r!?ya z)TBw1AP8#EV7GO2@AaI;oqT((v-dgN1JY3yNmN^qM3qzuh?r`Tq2dltc)&gD(VStM zPQ=t99o1T{kV6J({&G^5E#(5H?nd&Tw=IEvY_OupSiM4+Fo8#EVB7)dLw(f!latWC7Y*a!`9|MjU zLYQZ*BP}P{(pqX!qk6=$w_$8zvY=@kJ;WM z&I(}37bO=Nideg1Jkr0|O=md92!=6=g^nnBNEWbq#eeZ?H6^(`fqo2P)_p*|Bny~T z5&5)m`H0It_%Y?$CoegQSTEUB5px1D9>4=H0$mXDzK%yXd1|}{SmA1+~uNF*N%fMg_ E0ON=ds{jB1 literal 0 HcmV?d00001 From 7bbe9e6b9442bae2bf1a77b9706aa5a30751b5d7 Mon Sep 17 00:00:00 2001 From: Luca Greco Date: Wed, 9 Aug 2017 13:55:13 +0200 Subject: [PATCH 049/166] Bug 1388737 - Make about:debugging webextension popup test able to run with oop extension mode enabled. r=ochameau MozReview-Commit-ID: FsyDdPsQoLC --HG-- extra : rebase_source : 925a227a4791bfb95fc1a1f9bfe9ff12049eb91e --- .../addons/test-devtools-webextension/bg.js | 13 +- .../test-devtools-webextension/popup.js | 8 +- ...browser_addons_debug_webextension_popup.js | 113 +++++++++--------- 3 files changed, 68 insertions(+), 66 deletions(-) diff --git a/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/bg.js b/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/bg.js index 7ab93c46a029..6f48fcd08f00 100644 --- a/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/bg.js +++ b/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/bg.js @@ -8,13 +8,16 @@ document.body.innerText = "Background Page Body Test Content"; -// This function are called from the webconsole test: -// browser_addons_debug_webextension.js +// These functions are called from the following about:debugging tests: +// - browser_addons_debug_webextension.js +// - browser_addons_debug_webextension_popup.js -function myWebExtensionAddonFunction() { // eslint-disable-line no-unused-vars +// eslint-disable-next-line no-unused-vars +function myWebExtensionAddonFunction() { console.log("Background page function called", browser.runtime.getManifest()); } -function myWebExtensionShowPopup() { // eslint-disable-line no-unused-vars - console.log("readyForOpenPopup"); +// eslint-disable-next-line no-unused-vars +function myWebExtensionShowPopup() { + browser.test.sendMessage("readyForOpenPopup"); } diff --git a/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/popup.js b/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/popup.js index 035375682d67..02a573fad587 100644 --- a/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/popup.js +++ b/devtools/client/aboutdebugging/test/addons/test-devtools-webextension/popup.js @@ -6,8 +6,10 @@ "use strict"; -// This function is called from the webconsole test: +// This function is called from the following about:debugging test: // browser_addons_debug_webextension.js -function myWebExtensionPopupAddonFunction() { // eslint-disable-line no-unused-vars - console.log("Popup page function called", browser.runtime.getManifest()); +// +// eslint-disable-next-line no-unused-vars +function myWebExtensionPopupAddonFunction() { + browser.test.sendMessage("popupPageFunctionCalled", browser.runtime.getManifest()); } diff --git a/devtools/client/aboutdebugging/test/browser_addons_debug_webextension_popup.js b/devtools/client/aboutdebugging/test/browser_addons_debug_webextension_popup.js index 2dda95cd4e09..62b9086d7eac 100644 --- a/devtools/client/aboutdebugging/test/browser_addons_debug_webextension_popup.js +++ b/devtools/client/aboutdebugging/test/browser_addons_debug_webextension_popup.js @@ -37,28 +37,48 @@ function makeWidgetId(id) { } add_task(function* testWebExtensionsToolboxSwitchToPopup() { + let onReadyForOpenPopup; + let onPopupCustomMessage; + + Management.on("startup", function listener(event, extension) { + if (extension.name != ADDON_NAME) { + return; + } + + Management.off("startup", listener); + + function waitForExtensionTestMessage(expectedMessage) { + return new Promise(done => { + extension.on("test-message", function testLogListener(evt, ...args) { + const [message, ] = args; + + if (message !== expectedMessage) { + return; + } + + extension.off("test-message", testLogListener); + done(args); + }); + }); + } + + // Wait for the test script running in the browser toolbox process + // to be ready for selecting the popup page in the frame list selector. + onReadyForOpenPopup = waitForExtensionTestMessage("readyForOpenPopup"); + + // Wait for a notification sent by a script evaluated the test addon via + // the web console. + onPopupCustomMessage = waitForExtensionTestMessage("popupPageFunctionCalled"); + }); + let { tab, document, debugBtn, } = yield setupTestAboutDebuggingWebExtension(ADDON_NAME, ADDON_MANIFEST_PATH); - let onReadyForOpenPopup = new Promise(done => { - Services.obs.addObserver(function listener(message, topic) { - let apiMessage = message.wrappedJSObject; - if (apiMessage.addonId != ADDON_ID) { - return; - } - - if (apiMessage.arguments[0] == "readyForOpenPopup") { - Services.obs.removeObserver(listener, "console-api-log-event"); - done(); - } - }, "console-api-log-event"); - }); - // Be careful, this JS function is going to be executed in the addon toolbox, // which lives in another process. So do not try to use any scope variable! - let env = Cc["@mozilla.org/process/environment;1"] - .getService(Ci.nsIEnvironment); + let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment); + let testScript = function () { /* eslint-disable no-undef */ @@ -66,7 +86,7 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() { let popupFramePromise; toolbox.selectTool("webconsole") - .then(console => { + .then(async (console) => { dump(`Clicking the noautohide button\n`); toolbox.doc.getElementById("command-button-noautohide").click(); dump(`Clicked the noautohide button\n`); @@ -81,32 +101,25 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() { toolbox.target.on("frame-update", listener); }); - let waitForFrameListUpdate = new Promise((done) => { - toolbox.target.once("frame-update", () => { - done(console); - }); - }); + let waitForFrameListUpdate = toolbox.target.once("frame-update"); jsterm = console.hud.jsterm; jsterm.execute("myWebExtensionShowPopup()"); - // Wait the initial frame update (which list the background page). - return waitForFrameListUpdate; - }) - .then((console) => { - // Wait the new frame update (once the extension popup has been opened). - return popupFramePromise; - }) - .then(() => { + await Promise.all([ + // Wait the initial frame update (which list the background page). + waitForFrameListUpdate, + // Wait the new frame update (once the extension popup has been opened). + popupFramePromise, + ]); + dump(`Clicking the frame list button\n`); let btn = toolbox.doc.getElementById("command-button-frames"); - let menu = toolbox.showFramesMenu({target: btn}); + let frameMenu = toolbox.showFramesMenu({target: btn}); dump(`Clicked the frame list button\n`); - return menu.once("open").then(() => { - return menu; - }); - }) - .then(frameMenu => { + + await frameMenu.once("open"); + let frames = frameMenu.items; if (frames.length != 2) { @@ -125,12 +138,12 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() { popupFrameBtn.click(); - return waitForNavigated; + await waitForNavigated; + + await jsterm.execute("myWebExtensionPopupAddonFunction()"); + + await toolbox.destroy(); }) - .then(() => { - return jsterm.execute("myWebExtensionPopupAddonFunction()"); - }) - .then(() => toolbox.destroy()) .catch((error) => { dump("Error while running code in the browser toolbox process:\n"); dump(error + "\n"); @@ -143,22 +156,6 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() { env.set("MOZ_TOOLBOX_TEST_SCRIPT", ""); }); - // Wait for a notification sent by a script evaluated the test addon via - // the web console. - let onPopupCustomMessage = new Promise(done => { - Services.obs.addObserver(function listener(message, topic) { - let apiMessage = message.wrappedJSObject; - if (apiMessage.addonId != ADDON_ID) { - return; - } - - if (apiMessage.arguments[0] == "Popup page function called") { - Services.obs.removeObserver(listener, "console-api-log-event"); - done(apiMessage.arguments); - } - }, "console-api-log-event"); - }); - let onToolboxClose = BrowserToolboxProcess.once("close"); debugBtn.click(); @@ -174,7 +171,7 @@ add_task(function* testWebExtensionsToolboxSwitchToPopup() { let args = yield onPopupCustomMessage; ok(true, "Received console message from the popup page function as expected"); - is(args[0], "Popup page function called", "Got the expected console message"); + is(args[0], "popupPageFunctionCalled", "Got the expected console message"); is(args[1] && args[1].name, ADDON_NAME, "Got the expected manifest from WebExtension API"); From 5eb994379fe13cbdc5cc9de7b088780fa48f6f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 9 Aug 2017 11:58:12 -0500 Subject: [PATCH 050/166] servo: Merge #18022 - style: Only zoom absolute lengths (from emilio:text-zoom-woes); r=Manishearth As silly as it may seem to specify font-sizes using viewport units, we weren't handling zoom for them correctly either. Bug: 1388588 Reviewed-by: Manishearth MozReview-Commit-ID: 3Q6phYAu5CE Source-Repo: https://github.com/servo/servo Source-Revision: 1457f999099b74df8822750ff16628443402d408 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f0f0bcbbd8321608f814b01e2522c5f9e6b43de6 --- .../style/properties/longhand/font.mako.rs | 13 +++++++-- servo/components/style/values/computed/mod.rs | 3 +- .../components/style/values/specified/text.rs | 29 +++++++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/servo/components/style/properties/longhand/font.mako.rs b/servo/components/style/properties/longhand/font.mako.rs index 8d8fcf017ec0..96ba9199bf25 100644 --- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -844,8 +844,11 @@ ${helpers.single_keyword_system("font-variant-caps", } /// Compute it against a given base font size - pub fn to_computed_value_against(&self, context: &Context, base_size: FontBaseSize) - -> NonNegativeAu { + pub fn to_computed_value_against( + &self, + context: &Context, + base_size: FontBaseSize, + ) -> NonNegativeAu { use values::specified::length::FontRelativeLength; match *self { SpecifiedValue::Length(LengthOrPercentage::Length( @@ -856,9 +859,13 @@ ${helpers.single_keyword_system("font-variant-caps", NoCalcLength::ServoCharacterWidth(value))) => { value.to_computed_value(base_size.resolve(context)).into() } - SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { + SpecifiedValue::Length(LengthOrPercentage::Length( + NoCalcLength::Absolute(ref l))) => { context.maybe_zoom_text(l.to_computed_value(context).into()) } + SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { + l.to_computed_value(context).into() + } SpecifiedValue::Length(LengthOrPercentage::Percentage(pc)) => { base_size.resolve(context).scale_by(pc.0).into() } diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index a1206529f80a..104c0fcd14aa 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -135,8 +135,7 @@ impl<'a> Context<'a> { &self.builder } - - /// Apply text-zoom if enabled + /// Apply text-zoom if enabled. #[cfg(feature = "gecko")] pub fn maybe_zoom_text(&self, size: NonNegativeAu) -> NonNegativeAu { // We disable zoom for by unsetting the diff --git a/servo/components/style/values/specified/text.rs b/servo/components/style/values/specified/text.rs index 8341d6236f1b..08a59e87ff6e 100644 --- a/servo/components/style/values/specified/text.rs +++ b/servo/components/style/values/specified/text.rs @@ -84,6 +84,7 @@ impl ToComputedValue for LineHeight { #[inline] fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + use values::specified::length::FontBaseSize; match *self { GenericLineHeight::Normal => { GenericLineHeight::Normal @@ -97,23 +98,33 @@ impl ToComputedValue for LineHeight { }, GenericLineHeight::Length(ref non_negative_lop) => { let result = match non_negative_lop.0 { + LengthOrPercentage::Length(NoCalcLength::Absolute(ref abs)) => { + context.maybe_zoom_text(abs.to_computed_value(context).into()) + } LengthOrPercentage::Length(ref length) => { - context.maybe_zoom_text(length.to_computed_value(context).into()) + length.to_computed_value(context).into() }, LengthOrPercentage::Percentage(ref p) => { - let font_relative_length = - Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(p.0))); - font_relative_length.to_computed_value(context).into() + FontRelativeLength::Em(p.0) + .to_computed_value( + context, + FontBaseSize::CurrentStyle, + ).into() } LengthOrPercentage::Calc(ref calc) => { let computed_calc = calc.to_computed_value_zoomed(context); let font_relative_length = - Length::NoCalc(NoCalcLength::FontRelative( - FontRelativeLength::Em(computed_calc.percentage()))); + FontRelativeLength::Em(computed_calc.percentage()) + .to_computed_value( + context, + FontBaseSize::CurrentStyle, + ); + let absolute_length = computed_calc.unclamped_length(); - computed_calc.clamping_mode.clamp( - absolute_length + font_relative_length.to_computed_value(context) - ).into() + computed_calc + .clamping_mode + .clamp(absolute_length + font_relative_length) + .into() } }; GenericLineHeight::Length(result) From 94fc7ac2b357fca7b94f8472f8ea369f524c3b5d Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 8 Aug 2017 16:01:36 -0700 Subject: [PATCH 051/166] Bug 1387764 - Disable WebRender if HW_COMPOSITING is disabled. r=kats MozReview-Commit-ID: 5XSAw1tdi0P --HG-- extra : rebase_source : a3d20cc54c3cc7272a9e83f65c9bbd85cf31f71a --- gfx/thebes/gfxPlatform.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index d2a2110d3105..a4f8c353bb5c 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2447,6 +2447,14 @@ gfxPlatform::InitWebRenderConfig() } } + // HW_COMPOSITING being disabled implies interfacing with the GPU might break + if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) { + featureWebRender.ForceDisable( + FeatureStatus::Unavailable, + "Hardware compositing is disabled", + NS_LITERAL_CSTRING("FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP")); + } + // WebRender relies on the GPU process when on Windows #ifdef XP_WIN if (!gfxConfig::IsEnabled(Feature::GPU_PROCESS)) { From d408f82c902364eb6c7669f96ad7a11b81abfdec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Wed, 9 Aug 2017 20:12:36 +0200 Subject: [PATCH 052/166] Bug 1377184 - Consistently use the custom toolbar button styling in all browser toolbars. r=johannh MozReview-Commit-ID: DvMorv7HhDu --HG-- extra : rebase_source : 2f881aecd4aa668aa4b33f5b1c103fe2b7df4bbe --- browser/base/content/browser.xul | 2 +- .../performance/browser_startup_images.js | 10 +--- browser/themes/linux/browser.css | 22 -------- browser/themes/osx/browser.css | 36 ------------ browser/themes/shared/tabs.inc.css | 5 -- .../themes/shared/toolbarbutton-icons.inc.css | 1 + browser/themes/shared/toolbarbuttons.inc.css | 52 ++++++++---------- browser/themes/windows/browser.css | 22 -------- .../osx/global/icons/chevron-inverted.png | Bin 247 -> 0 bytes .../osx/global/icons/chevron-inverted@2x.png | Bin 481 -> 0 bytes toolkit/themes/osx/global/icons/chevron.png | Bin 251 -> 0 bytes .../themes/osx/global/icons/chevron@2x.png | Bin 462 -> 0 bytes toolkit/themes/osx/global/jar.mn | 4 -- toolkit/themes/shared/non-mac.jar.inc.mn | 2 - .../global/toolbar/chevron-inverted.png | Bin 85 -> 0 bytes .../themes/windows/global/toolbar/chevron.gif | Bin 57 -> 0 bytes 16 files changed, 28 insertions(+), 128 deletions(-) delete mode 100644 toolkit/themes/osx/global/icons/chevron-inverted.png delete mode 100644 toolkit/themes/osx/global/icons/chevron-inverted@2x.png delete mode 100644 toolkit/themes/osx/global/icons/chevron.png delete mode 100644 toolkit/themes/osx/global/icons/chevron@2x.png delete mode 100644 toolkit/themes/windows/global/toolbar/chevron-inverted.png delete mode 100644 toolkit/themes/windows/global/toolbar/chevron.gif diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index c1db021ffc0c..4e50030faa7b 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -1116,7 +1116,7 @@ flex="1"/> .toolbarbutton-icon { - transform: scaleX(-1); -} - -toolbarbutton.chevron > .toolbarbutton-text, -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - -toolbarbutton.chevron > .toolbarbutton-icon { - margin: 0; -} - /* Status panel */ .statuspanel-label { diff --git a/browser/themes/osx/browser.css b/browser/themes/osx/browser.css index afab1f427593..d38bd925f513 100644 --- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -195,38 +195,6 @@ -moz-box-align: center; } -toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron.png"); - margin: 1px 0 0; - padding: 0; -} - -toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron-inverted.png"); -} - -toolbarbutton.chevron > .toolbarbutton-text { - display: none; -} - -toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { - transform: scaleX(-1); -} - -@media (min-resolution: 2dppx) { - toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron@2x.png"); - } - - toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/icons/chevron-inverted@2x.png"); - } - - toolbarbutton.chevron > .toolbarbutton-icon { - width: 13px; - } -} - /* ----- BOOKMARK BUTTONS ----- */ .bookmark-item[container] { @@ -1072,10 +1040,6 @@ html|span.ac-emphasize-text-url { text-shadow: none; } -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - .bookmark-item { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg"); } diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index de83e90cbb6e..2dc39d514952 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -443,9 +443,6 @@ #TabsToolbar > #new-tab-button , #TabsToolbar > toolbarpaletteitem > #new-tab-button { list-style-image: url(chrome://browser/skin/tabbrowser/newtab.svg); - -moz-context-properties: fill; - fill: currentColor; - color: inherit; } .tabs-newtab-button { @@ -466,8 +463,6 @@ #alltabs-button { list-style-image: url(chrome://browser/skin/arrow-dropdown-16.svg); - -moz-context-properties: fill; - fill: currentColor; } .alltabs-item > .menu-iconic-left > .menu-iconic-icon { diff --git a/browser/themes/shared/toolbarbutton-icons.inc.css b/browser/themes/shared/toolbarbutton-icons.inc.css index 3349d31ae39e..80526d6265a9 100644 --- a/browser/themes/shared/toolbarbutton-icons.inc.css +++ b/browser/themes/shared/toolbarbutton-icons.inc.css @@ -300,6 +300,7 @@ toolbar:not([brighttext]) #bookmarks-menu-button[starred] > .toolbarbutton-menub list-style-image: url("chrome://browser/skin/zoom-in.svg"); } +#PlacesChevron, #nav-bar-overflow-button { list-style-image: url("chrome://browser/skin/chevron.svg"); } diff --git a/browser/themes/shared/toolbarbuttons.inc.css b/browser/themes/shared/toolbarbuttons.inc.css index e9055f24bbd7..52692b3cba7a 100644 --- a/browser/themes/shared/toolbarbuttons.inc.css +++ b/browser/themes/shared/toolbarbuttons.inc.css @@ -11,8 +11,8 @@ --backbutton-background: hsla(0,100%,100%,.8); --backbutton-hover-background: var(--backbutton-background); --backbutton-active-background: var(--toolbarbutton-active-background); - --backbutton-border-color: hsla(240,5%,5%,.3); + /* This default value of --toolbarbutton-height is defined to prevent CSS errors for an invalid variable. The value should not get used, as a more specific value should be set when the value will be used. */ @@ -49,8 +49,8 @@ toolbar[brighttext] { margin-inline-end: 0; } -:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-icon, -:-moz-any(toolbar, .widget-overflow-list) .toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { +.toolbarbutton-1 > .toolbarbutton-icon, +.toolbarbutton-1 > .toolbarbutton-badge-stack > .toolbarbutton-icon { max-width: 16px; } @@ -60,7 +60,6 @@ toolbar[brighttext] { margin: 0 0 var(--tab-toolbar-navbar-overlap); } -#TabsToolbar .toolbarbutton-1, .tabbrowser-arrowscrollbox > .scrollbutton-up, .tabbrowser-arrowscrollbox > .scrollbutton-down { -moz-appearance: none; @@ -89,49 +88,48 @@ toolbar[brighttext] { padding: 0; } -#nav-bar .toolbarbutton-1 { +toolbar .toolbarbutton-1 { -moz-appearance: none; margin: 0; padding: 0 2px; -moz-box-pack: center; } -#nav-bar #PanelUI-menu-button { +#PanelUI-menu-button { padding-inline-start: 5px; padding-inline-end: 5px; } -#nav-bar .toolbarbutton-1 > menupopup { +toolbar .toolbarbutton-1 > menupopup { margin-top: -3px; } -#nav-bar .toolbarbutton-1 > menupopup.cui-widget-panel { +toolbar .toolbarbutton-1 > menupopup.cui-widget-panel { margin-top: -8px; } .findbar-button > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton), -#nav-bar .toolbarbutton-1 > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1 > .toolbarbutton-text, -#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1 > .toolbarbutton-icon, +toolbar .toolbarbutton-1 > .toolbarbutton-text, +toolbar .toolbarbutton-1 > .toolbarbutton-badge-stack { padding: var(--toolbarbutton-inner-padding); border-radius: var(--toolbarbutton-border-radius); transition-property: background-color, border-color, box-shadow; transition-duration: 150ms; } -#nav-bar .toolbarbutton-1 > .toolbarbutton-icon { +toolbar .toolbarbutton-1 > .toolbarbutton-icon { /* horizontal padding + actual icon width */ max-width: calc(2 * var(--toolbarbutton-inner-padding) + 16px); } .bookmark-item > .toolbarbutton-menu-dropmarker, -#TabsToolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker, -#nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { +toolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker { display: none; } -#nav-bar .toolbarbutton-1 > .toolbarbutton-text { +toolbar .toolbarbutton-1 > .toolbarbutton-text { padding-top: var(--toolbarbutton-vertical-text-padding); padding-bottom: 0; /* To make the hover feedback line up with sibling buttons, it needs the same @@ -141,17 +139,17 @@ toolbarbutton.bookmark-item:not(.subviewbutton), min-height: calc(16px + 2 * var(--toolbarbutton-inner-padding)); } -#nav-bar .toolbaritem-combined-buttons { +toolbar .toolbaritem-combined-buttons { margin-left: 2px; margin-right: 2px; } -#nav-bar .toolbaritem-combined-buttons > .toolbarbutton-1 { +toolbar .toolbaritem-combined-buttons > .toolbarbutton-1 { padding-left: 0; padding-right: 0; } -#nav-bar .toolbaritem-combined-buttons:not(:hover) > separator { +toolbar .toolbaritem-combined-buttons:not(:hover) > separator { content: ""; display: -moz-box; width: 1px; @@ -164,19 +162,17 @@ toolbarbutton.bookmark-item:not(.subviewbutton), opacity: .2; } -#nav-bar[brighttext] .toolbaritem-combined-buttons > separator { +toolbar[brighttext] .toolbaritem-combined-buttons > separator { opacity: .3; } -#TabsToolbar .toolbarbutton-1:not([disabled=true]):hover, -#TabsToolbar .toolbarbutton-1[open], .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled=true]):hover, .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled=true]):hover, .findbar-button:not(:-moz-any([checked="true"],[disabled="true"])):hover > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not([open]), -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, -#nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, +toolbar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-hover-background); color: inherit; } @@ -184,15 +180,15 @@ toolbarbutton.bookmark-item:not(.subviewbutton):hover:not([disabled="true"]):not .findbar-button:not([disabled=true]):-moz-any([checked="true"],:hover:active) > .toolbarbutton-text, toolbarbutton.bookmark-item:not(.subviewbutton):hover:active:not([disabled="true"]), toolbarbutton.bookmark-item[open="true"], -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, -#nav-bar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-icon, +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-text, +toolbar .toolbarbutton-1:not([disabled=true]):-moz-any([open],[checked],:hover:active) > .toolbarbutton-badge-stack { background-color: var(--toolbarbutton-active-background); transition-duration: 10ms; color: inherit; } -#nav-bar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { +toolbar .toolbarbutton-1[checked]:not(:active):hover > .toolbarbutton-icon { background-color: var(--toolbarbutton-hover-background); transition: background-color .4s; } diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index d88bbf8c90bb..6f0ffb2ad53c 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -1045,28 +1045,6 @@ treechildren.searchbar-treebody::-moz-tree-row(selected) { font-weight: bold; } - -toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/toolbar/chevron.gif") !important; -} - -toolbar[brighttext] toolbarbutton.chevron { - list-style-image: url("chrome://global/skin/toolbar/chevron-inverted.png") !important; -} - -toolbarbutton.chevron:-moz-locale-dir(rtl) > .toolbarbutton-icon { - transform: scaleX(-1); -} - -toolbarbutton.chevron > .toolbarbutton-text, -toolbarbutton.chevron > .toolbarbutton-menu-dropmarker { - display: none; -} - -toolbarbutton.chevron > .toolbarbutton-icon { - margin: 0; -} - /* Bookmarks toolbar */ #PlacesToolbarDropIndicator { list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png); diff --git a/toolkit/themes/osx/global/icons/chevron-inverted.png b/toolkit/themes/osx/global/icons/chevron-inverted.png deleted file mode 100644 index 8ad164baaf7d205f16d7d7742d2fdd09caf71efc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247 zcmV`q2*z3^2a)7uFo>%F3Vi(k&DK4(62e+2 z4U%MH;A1e%to#4||GWQRjNLNoA*|WrAbm^>0_`dP-~NB||GlGmTPlPVsR5QcVe|jP z|JVQDm?lmLhO!bEWPlRK%z#F`{QufEr#uS6vdd=BVc=pos0+0A)&Eysh3O#>mUjVz xE(15n8Db2!43P{$35OBIAEnFF&nX$tVSE;Hp7%VWBOoCR1#t%jAv$|G;T4=~Y`JFe3P&J$IU&NS zuXP$14omYLT?u(OiI1|ox7!^yV^dBJeq-Nr@t>&dBOR)bAwGKtZ99d~gpdSRpq z?lP41W0%6oag*6J8-)2mM;U4$Z?yzhaQ`VOk}zxT-1tayF_1Uvg1dtFI+6Ds9lWO5 zWJALE)CDDb@;}~ij!S^xeDzzbf1g-w@1hy$sU|os0rulGwot}HJVFJxaFymmqT`dl Xk4DNQT~lE;00000NkvXXu0mjfX1>!~ diff --git a/toolkit/themes/osx/global/icons/chevron.png b/toolkit/themes/osx/global/icons/chevron.png deleted file mode 100644 index b2d31e38f56dda9807001c84e1d2bc31ced0eb0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 251 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(0wkS_^Bw{z$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1Gb3I)gLpY+769m#DP8#$lDmE(!aWnnnj?GQcNI#J_!_JZK zSki-L&#st^6pbX0)ERpM_)ciCY+7dU;eg6f|7*r7MlMD^_q6zv4GWx9jn7Cdl4z1B z(qa+R>FCjM)@_z|{`0y@Hq}7;Vd>v`z6mWV&Z^DU&PP65rK`4aalE!S_i$=i*sM53 v@t0$66I0LE`TVbb{O3*3Xi0F)VPtr}*M4EaiEoTRhcbA&`njxgN@xNAvglRU diff --git a/toolkit/themes/osx/global/icons/chevron@2x.png b/toolkit/themes/osx/global/icons/chevron@2x.png deleted file mode 100644 index dd91178030e5f6b315f642909617cce898cdfb7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmV;<0WtoGP)$^ zOG`pg6opriQi44uc1tt8r9@FC5s@kOen~Hiuqb=bLo32bl9XV9^iU%L8y7U{r!?ya z)TBw1AP8#EV7GO2@AaI;oqT((v-dgN1JY3yNmN^qM3qzuh?r`Tq2dltc)&gD(VStM zPQ=t99o1T{kV6J({&G^5E#(5H?nd&Tw=IEvY_OupSiM4+Fo8#EVB7)dLw(f!latWC7Y*a!`9|MjU zLYQZ*BP}P{(pqX!qk6=$w_$8zvY=@kJ;WM z&I(}37bO=Nideg1Jkr0|O=md92!=6=g^nnBNEWbq#eeZ?H6^(`fqo2P)_p*|Bny~T z5&5)m`H0It_%Y?$CoegQSTEUB5px1D9>4=H0$mXDzK%yXd1|}{SmA1+~uNF*N%fMg_ E0ON=ds{jB1 From 90d16273824e9577318ae34ce2df9ad6079b0102 Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Tue, 8 Aug 2017 17:14:28 -0400 Subject: [PATCH 053/166] Bug 1388464: Use SyncRunnable instead of DISPATCH_SYNC to actually block the main thread during the blocking preference file write. r=smaug MozReview-Commit-ID: 6J1252Q3pBr --HG-- extra : rebase_source : a2ede1a9e5a9cf6f26139c747404f6a62318207e --- modules/libpref/Preferences.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 579ee657227b..c7cb8f046815 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -11,6 +11,7 @@ #include "mozilla/Attributes.h" #include "mozilla/HashFunctions.h" #include "mozilla/ServoStyleSet.h" +#include "mozilla/SyncRunnable.h" #include "mozilla/Telemetry.h" #include "mozilla/UniquePtrExtensions.h" @@ -1239,9 +1240,13 @@ Preferences::WritePrefFile(nsIFile* aFile, SaveMethod aSaveMethod) do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { bool async = aSaveMethod == SaveMethod::Asynchronous; - rv = target->Dispatch(new PWRunnable(aFile), - async ? nsIEventTarget::DISPATCH_NORMAL : - nsIEventTarget::DISPATCH_SYNC); + if (async) { + rv = target->Dispatch(new PWRunnable(aFile), + nsIEventTarget::DISPATCH_NORMAL); + } else { + // Note that we don't get the nsresult return value here + SyncRunnable::DispatchToThread(target, new PWRunnable(aFile), true); + } return rv; } } From f10ce62128db34477f898f9cea6faea6b6681074 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 8 Aug 2017 15:43:17 -0400 Subject: [PATCH 054/166] Bug 1386483 - Split the wr_dp_push_clip method into two to allow reusing clips. r=jrmuizel MozReview-Commit-ID: 90BEJGs8wGg --HG-- extra : rebase_source : 9ef113bee43391c00912457afc395284899a23cb --- gfx/layers/wr/ScrollingLayersHelper.cpp | 6 +++-- gfx/webrender_bindings/WebRenderAPI.cpp | 27 ++++++++++++++----- gfx/webrender_bindings/WebRenderAPI.h | 6 +++-- gfx/webrender_bindings/src/bindings.rs | 20 +++++++++----- .../webrender_ffi_generated.h | 15 +++++++---- layout/painting/nsDisplayList.cpp | 3 ++- 6 files changed, 53 insertions(+), 24 deletions(-) diff --git a/gfx/layers/wr/ScrollingLayersHelper.cpp b/gfx/layers/wr/ScrollingLayersHelper.cpp index 7600c696de2c..f2679dfde5d7 100644 --- a/gfx/layers/wr/ScrollingLayersHelper.cpp +++ b/gfx/layers/wr/ScrollingLayersHelper.cpp @@ -123,7 +123,8 @@ ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStacking Maybe mask = mLayer->BuildWrMaskLayer(aStackingContext); LayerRect clipRect = ViewAs(clip.ref(), PixelCastJustification::MovingDownToChildren); - mBuilder->PushClip(aStackingContext.ToRelativeLayoutRect(clipRect), mask.ptrOr(nullptr)); + mBuilder->PushClip(mBuilder->DefineClip( + aStackingContext.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr))); mPushedLayerLocalClip = true; } } @@ -141,7 +142,8 @@ ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip, // TODO: check this transform is correct in all cases mask = maskWrLayer->RenderMaskLayer(aSc, maskLayer->GetTransform()); } - mBuilder->PushClip(aSc.ToRelativeLayoutRect(clipRect), mask.ptrOr(nullptr)); + mBuilder->PushClip(mBuilder->DefineClip( + aSc.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr))); } ScrollingLayersHelper::~ScrollingLayersHelper() diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 9ad06ca4e9c1..5b8f2d916686 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -664,15 +664,28 @@ DisplayListBuilder::PopStackingContext() wr_dp_pop_stacking_context(mWrState); } -void -DisplayListBuilder::PushClip(const wr::LayoutRect& aClipRect, - const wr::WrImageMask* aMask) +wr::WrClipId +DisplayListBuilder::DefineClip(const wr::LayoutRect& aClipRect, + const nsTArray* aComplex, + const wr::WrImageMask* aMask) { - uint64_t clip_id = wr_dp_push_clip(mWrState, aClipRect, nullptr, 0, aMask); - WRDL_LOG("PushClip id=%" PRIu64 " r=%s m=%p b=%s\n", clip_id, + uint64_t clip_id = wr_dp_define_clip(mWrState, aClipRect, + aComplex ? aComplex->Elements() : nullptr, + aComplex ? aComplex->Length() : 0, + aMask); + WRDL_LOG("DefineClip id=%" PRIu64 " r=%s m=%p b=%s complex=%d\n", clip_id, Stringify(aClipRect).c_str(), aMask, - aMask ? Stringify(aMask->rect).c_str() : "none"); - mClipIdStack.push_back(wr::WrClipId { clip_id }); + aMask ? Stringify(aMask->rect).c_str() : "none", + aComplex ? aComplex->Length() : 0); + return wr::WrClipId { clip_id }; +} + +void +DisplayListBuilder::PushClip(const wr::WrClipId& aClipId) +{ + wr_dp_push_clip(mWrState, aClipId.id); + WRDL_LOG("PushClip id=%" PRIu64 "\n", aClipId.id); + mClipIdStack.push_back(aClipId); } void diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index c44c31f3af43..ac551c83a6e3 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -177,8 +177,10 @@ public: const nsTArray& aFilters); void PopStackingContext(); - void PushClip(const wr::LayoutRect& aClipRect, - const wr::WrImageMask* aMask); + wr::WrClipId DefineClip(const wr::LayoutRect& aClipRect, + const nsTArray* aComplex = nullptr, + const wr::WrImageMask* aMask = nullptr); + void PushClip(const wr::WrClipId& aClipId); void PopClip(); void PushBuiltDisplayList(wr::BuiltDisplayList &dl); diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index dbcebb4b76ae..65d2881c7c27 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -1053,12 +1053,12 @@ pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) { } #[no_mangle] -pub extern "C" fn wr_dp_push_clip(state: &mut WrState, - rect: LayoutRect, - complex: *const WrComplexClipRegion, - complex_count: usize, - mask: *const WrImageMask) - -> u64 { +pub extern "C" fn wr_dp_define_clip(state: &mut WrState, + rect: LayoutRect, + complex: *const WrComplexClipRegion, + complex_count: usize, + mask: *const WrImageMask) + -> u64 { assert!(unsafe { is_in_main_thread() }); let clip_rect: LayoutRect = rect.into(); let complex_slice = make_slice(complex, complex_count); @@ -1066,7 +1066,6 @@ pub extern "C" fn wr_dp_push_clip(state: &mut WrState, let mask : Option = unsafe { mask.as_ref() }.map(|x| x.into()); let clip_id = state.frame_builder.dl_builder.define_clip(None, clip_rect, complex_iter, mask); - state.frame_builder.dl_builder.push_clip_id(clip_id); // return the u64 id value from inside the ClipId::Clip(..) match clip_id { ClipId::Clip(id, nesting_index, pipeline_id) => { @@ -1078,6 +1077,13 @@ pub extern "C" fn wr_dp_push_clip(state: &mut WrState, } } +#[no_mangle] +pub extern "C" fn wr_dp_push_clip(state: &mut WrState, + clip_id: u64) { + assert!(unsafe { is_in_main_thread() }); + state.frame_builder.dl_builder.push_clip_id(ClipId::Clip(clip_id, 0, state.pipeline_id)); +} + #[no_mangle] pub extern "C" fn wr_dp_pop_clip(state: &mut WrState) { assert!(unsafe { !is_in_render_thread() }); diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index b3a81bc48b6a..b15b405e2b1a 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -772,6 +772,14 @@ void wr_dp_begin(WrState *aState, uint32_t aHeight) WR_FUNC; +WR_INLINE +uint64_t wr_dp_define_clip(WrState *aState, + LayoutRect aRect, + const WrComplexClipRegion *aComplex, + size_t aComplexCount, + const WrImageMask *aMask) +WR_FUNC; + WR_INLINE void wr_dp_end(WrState *aState) WR_FUNC; @@ -862,11 +870,8 @@ void wr_dp_push_built_display_list(WrState *aState, WR_FUNC; WR_INLINE -uint64_t wr_dp_push_clip(WrState *aState, - LayoutRect aRect, - const WrComplexClipRegion *aComplex, - size_t aComplexCount, - const WrImageMask *aMask) +void wr_dp_push_clip(WrState *aState, + uint64_t aClipId) WR_FUNC; WR_INLINE diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 87c7e76397d1..2ecb476f9b3a 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -8938,7 +8938,8 @@ nsDisplayMask::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder Maybe mask = aManager->BuildWrMaskImage(this, aBuilder, aSc, aDisplayListBuilder, bounds); if (mask) { - aBuilder.PushClip(aSc.ToRelativeLayoutRect(bounds), mask.ptr()); + aBuilder.PushClip(aBuilder.DefineClip( + aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr())); } nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aSc, aParentCommands, aManager, aDisplayListBuilder); From b36bbd4e9a1ebc0fa255117c71ad229b63948bf6 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 8 Aug 2017 15:43:29 -0400 Subject: [PATCH 055/166] Bug 1386483 - Push, push, push the clips, caching all the way. r=jrmuizel,mstange This patch ensures that we push clips in WR for each display item, reflecting the display item's clip chain as computed in Gecko. A display item will often share part or most of its clip chain with other display items, so we try to reuse the corresponding WR clip ids as much as we can instead of defining new duplicated clips. MozReview-Commit-ID: LkBh8LIpQ4J --HG-- extra : rebase_source : 5af1de0931f1d059e98b5c66b15988961503e114 --- gfx/layers/wr/ScrollingLayersHelper.cpp | 64 +++++++++++++++++++++++++ gfx/layers/wr/ScrollingLayersHelper.h | 13 +++++ gfx/layers/wr/WebRenderLayerManager.cpp | 15 ++++-- gfx/layers/wr/WebRenderLayerManager.h | 15 ++++++ gfx/webrender_bindings/WebRenderTypes.h | 4 ++ 5 files changed, 106 insertions(+), 5 deletions(-) diff --git a/gfx/layers/wr/ScrollingLayersHelper.cpp b/gfx/layers/wr/ScrollingLayersHelper.cpp index f2679dfde5d7..540500158022 100644 --- a/gfx/layers/wr/ScrollingLayersHelper.cpp +++ b/gfx/layers/wr/ScrollingLayersHelper.cpp @@ -21,6 +21,7 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer, : mLayer(aLayer) , mBuilder(&aBuilder) , mPushedLayerLocalClip(false) + , mClipsPushed(0) { if (!mLayer->WrManager()->AsyncPanZoomEnabled()) { // If APZ is disabled then we don't need to push the scrolling clips. We @@ -107,6 +108,60 @@ ScrollingLayersHelper::ScrollingLayersHelper(WebRenderLayer* aLayer, } } +ScrollingLayersHelper::ScrollingLayersHelper(nsDisplayItem* aItem, + wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aStackingContext, + WebRenderLayerManager::ClipIdMap& aCache) + : mLayer(nullptr) + , mBuilder(&aBuilder) + , mPushedLayerLocalClip(false) + , mClipsPushed(0) +{ + DefineAndPushChain(aItem->GetClipChain(), aBuilder, aStackingContext, + aItem->Frame()->PresContext()->AppUnitsPerDevPixel(), aCache); +} + +void +ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain, + wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aStackingContext, + int32_t aAppUnitsPerDevPixel, + WebRenderLayerManager::ClipIdMap& aCache) +{ + if (!aChain) { + return; + } + auto it = aCache.find(aChain); + Maybe clipId = (it != aCache.end() ? Some(it->second) : Nothing()); + if (clipId && clipId == aBuilder.TopmostClipId()) { + // it was already in the cache and pushed on the WR clip stack, so we don't + // need to recurse any further. + return; + } + // Recurse up the clip chain to make sure all ancestor clips are defined and + // pushed onto the WR clip stack. Note that the recursion can invalidate the + // iterator `it`. + DefineAndPushChain(aChain->mParent, aBuilder, aStackingContext, aAppUnitsPerDevPixel, aCache); + + if (!aChain->mClip.HasClip()) { + // This item in the chain is a no-op, skip over it + return; + } + if (!clipId) { + // If we don't have a clip id for this chain item yet, define the clip in WR + // and save the id + LayoutDeviceRect clip = LayoutDeviceRect::FromAppUnits( + aChain->mClip.GetClipRect(), aAppUnitsPerDevPixel); + // TODO: deal with rounded corners here + clipId = Some(aBuilder.DefineClip(aStackingContext.ToRelativeLayoutRect(clip))); + aCache[aChain] = clipId.value(); + } + // Finally, push the clip onto the WR stack + MOZ_ASSERT(clipId); + aBuilder.PushClip(clipId.value()); + mClipsPushed++; +} + void ScrollingLayersHelper::PushLayerLocalClip(const StackingContextHelper& aStackingContext) { @@ -148,6 +203,15 @@ ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip, ScrollingLayersHelper::~ScrollingLayersHelper() { + if (!mLayer) { + // For layers-free mode + while (mClipsPushed > 0) { + mBuilder->PopClip(); + mClipsPushed--; + } + return; + } + Layer* layer = mLayer->GetLayer(); if (!mLayer->WrManager()->AsyncPanZoomEnabled()) { if (mPushedLayerLocalClip) { diff --git a/gfx/layers/wr/ScrollingLayersHelper.h b/gfx/layers/wr/ScrollingLayersHelper.h index bd64a77bf238..61df01f96979 100644 --- a/gfx/layers/wr/ScrollingLayersHelper.h +++ b/gfx/layers/wr/ScrollingLayersHelper.h @@ -7,9 +7,12 @@ #define GFX_SCROLLINGLAYERSHELPER_H #include "mozilla/Attributes.h" +#include "mozilla/layers/WebRenderLayerManager.h" namespace mozilla { +struct DisplayItemClipChain; + namespace wr { class DisplayListBuilder; } @@ -26,9 +29,18 @@ public: ScrollingLayersHelper(WebRenderLayer* aLayer, wr::DisplayListBuilder& aBuilder, const StackingContextHelper& aSc); + ScrollingLayersHelper(nsDisplayItem* aItem, + wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aStackingContext, + WebRenderLayerManager::ClipIdMap& aCache); ~ScrollingLayersHelper(); private: + void DefineAndPushChain(const DisplayItemClipChain* aChain, + wr::DisplayListBuilder& aBuilder, + const StackingContextHelper& aStackingContext, + int32_t aAppUnitsPerDevPixel, + WebRenderLayerManager::ClipIdMap& aCache); void PushLayerLocalClip(const StackingContextHelper& aStackingContext); void PushLayerClip(const LayerClip& aClip, const StackingContextHelper& aSc); @@ -36,6 +48,7 @@ private: WebRenderLayer* mLayer; wr::DisplayListBuilder* mBuilder; bool mPushedLayerLocalClip; + int mClipsPushed; }; } // namespace layers diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 1b5a6f2921b4..95c115f65023 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -264,11 +264,15 @@ WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDi } } - // Note: this call to CreateWebRenderCommands can recurse back into - // this function if the |item| is a wrapper for a sublist. - if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this, - aDisplayListBuilder)) { - PushItemAsImage(item, aBuilder, aSc, aDisplayListBuilder); + { // scope the ScrollingLayersHelper + ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache); + + // Note: this call to CreateWebRenderCommands can recurse back into + // this function if the |item| is a wrapper for a sublist. + if (!item->CreateWebRenderCommands(aBuilder, aSc, mParentCommands, this, + aDisplayListBuilder)) { + PushItemAsImage(item, aBuilder, aSc, aDisplayListBuilder); + } } if (apzEnabled && forceNewLayerData) { @@ -624,6 +628,7 @@ WebRenderLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback mScrollData.AddLayerData(*i); } mLayerScrollData.clear(); + mClipIdCache.clear(); } else { for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) { RefPtr canvasData = iter.Get()->GetKey(); diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index f9cabc4897f9..45014f226b2c 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -273,6 +273,21 @@ private: // tree don't duplicate scroll metadata that their ancestors already have. std::vector mAsrStack; +public: + // Note: two DisplayItemClipChain* A and B might actually be "equal" (as per + // DisplayItemClipChain::Equal(A, B)) even though they are not the same pointer + // (A != B). In this hopefully-rare case, they will get separate entries + // in this map when in fact we could collapse them. However, to collapse + // them involves writing a custom hash function for the pointer type such that + // A and B hash to the same things whenever DisplayItemClipChain::Equal(A, B) + // is true, and that will incur a performance penalty for all the hashmap + // operations, so is probably not worth it. With the current code we might + // end up creating multiple clips in WR that are effectively identical but + // have separate clip ids. Hopefully this won't happen very often. + typedef std::unordered_map ClipIdMap; +private: + ClipIdMap mClipIdCache; + // Layers that have been mutated. If we have an empty transaction // then a display item layer will no longer be valid // if it was a mutated layers. diff --git a/gfx/webrender_bindings/WebRenderTypes.h b/gfx/webrender_bindings/WebRenderTypes.h index 05bd9631708b..2e96fab6523b 100644 --- a/gfx/webrender_bindings/WebRenderTypes.h +++ b/gfx/webrender_bindings/WebRenderTypes.h @@ -649,6 +649,10 @@ static inline wr::WrFilterOp ToWrFilterOp(const layers::CSSFilter& filter) { // and the compiler will catch accidental conversions between the two. struct WrClipId { uint64_t id; + + bool operator==(const WrClipId& other) const { + return id == other.id; + } }; } // namespace wr From 499e5efc524214c344f62e87dd8e4ba856138a3f Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Sun, 6 Aug 2017 09:42:55 -0700 Subject: [PATCH 056/166] Bug 1368291 - Style sharing for lazy pseudos. r=emilio MozReview-Commit-ID: 9u8FzDXFZcX --- layout/style/ServoStyleContext.cpp | 21 ++++++++++++ layout/style/ServoStyleContext.h | 52 +++++++++++++++++++++++++++--- layout/style/ServoStyleSet.cpp | 45 +++++++++++++++++++------- layout/style/nsCSSPseudoElements.h | 7 ++++ 4 files changed, 109 insertions(+), 16 deletions(-) diff --git a/layout/style/ServoStyleContext.cpp b/layout/style/ServoStyleContext.cpp index 9718624bd5fd..31c0f92d378b 100644 --- a/layout/style/ServoStyleContext.cpp +++ b/layout/style/ServoStyleContext.cpp @@ -52,4 +52,25 @@ ServoStyleContext::GetCachedInheritingAnonBoxStyle(nsIAtom* aAnonBox) const return current; } +ServoStyleContext* +ServoStyleContext::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const +{ + MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo && + aPseudo != CSSPseudoElementType::InheritingAnonBox && + aPseudo != CSSPseudoElementType::NonInheritingAnonBox); + MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "Lazy pseudos can't inherit lazy pseudos"); + + if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudo)) { + return nullptr; + } + + auto* current = mNextLazyPseudoStyle.get(); + + while (current && current->GetPseudoType() != aPseudo) { + current = current->mNextLazyPseudoStyle.get(); + } + + return current; +} + } // namespace mozilla diff --git a/layout/style/ServoStyleContext.h b/layout/style/ServoStyleContext.h index ffbfbdc1eff4..a969e8ec516a 100644 --- a/layout/style/ServoStyleContext.h +++ b/layout/style/ServoStyleContext.h @@ -34,13 +34,19 @@ public: return ComputedData()->visited_style.mPtr; } + bool IsLazilyCascadedPseudoElement() const + { + return IsPseudoElement() && + !nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType()); + } + ServoStyleContext* GetCachedInheritingAnonBoxStyle(nsIAtom* aAnonBox) const; void SetCachedInheritedAnonBoxStyle(nsIAtom* aAnonBox, - ServoStyleContext& aStyle) + ServoStyleContext* aStyle) { MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox)); - MOZ_ASSERT(!aStyle.mNextInheritingAnonBoxStyle); + MOZ_ASSERT(!aStyle->mNextInheritingAnonBoxStyle); // NOTE(emilio): Since we use it to cache inheriting anon boxes in a linked // list, we can't use that cache if the style we're inheriting from is an @@ -52,8 +58,35 @@ public: return; } - mNextInheritingAnonBoxStyle.swap(aStyle.mNextInheritingAnonBoxStyle); - mNextInheritingAnonBoxStyle = &aStyle; + mNextInheritingAnonBoxStyle.swap(aStyle->mNextInheritingAnonBoxStyle); + mNextInheritingAnonBoxStyle = aStyle; + } + + ServoStyleContext* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const; + + void SetCachedLazyPseudoStyle(ServoStyleContext* aStyle) + { + MOZ_ASSERT(aStyle->GetPseudo() && !aStyle->IsAnonBox()); + MOZ_ASSERT(!GetCachedLazyPseudoStyle(aStyle->GetPseudoType())); + MOZ_ASSERT(!aStyle->mNextLazyPseudoStyle); + MOZ_ASSERT(!IsLazilyCascadedPseudoElement(), "lazy pseudos can't inherit lazy pseudos"); + MOZ_ASSERT(aStyle->IsLazilyCascadedPseudoElement()); + + // Since we're caching lazy pseudo styles on the ComputedValues of the + // originating element, we can assume that we either have the same + // originating element, or that they were at least similar enough to share + // the same ComputedValues, which means that they would match the same + // pseudo rules. This allows us to avoid matching selectors and checking + // the rule node before deciding to share. + // + // The one place this optimization breaks is with pseudo-elements that + // support state (like :hover). So we just avoid sharing in those cases. + if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aStyle->GetPseudoType())) { + return; + } + + mNextLazyPseudoStyle.swap(aStyle->mNextLazyPseudoStyle); + mNextLazyPseudoStyle = aStyle; } /** @@ -72,6 +105,17 @@ private: // Otherwise it represents the next entry in the cache of the parent style // context. RefPtr mNextInheritingAnonBoxStyle; + + // A linked-list cache of lazy pseudo styles inheriting from this style _if + // the style isn't a lazy pseudo style itself_. + // + // Otherwise it represents the next entry in the cache of the parent style + // context. + // + // Note that we store these separately from inheriting anonymous boxes so that + // text nodes inheriting from lazy pseudo styles can share styles, which is + // very important on some pages. + RefPtr mNextLazyPseudoStyle; }; } // namespace mozilla diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index a1cd15903ade..83266904354b 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -414,7 +414,7 @@ ResolveStyleForTextOrFirstLetterContinuation( &aParent, inheritTarget).Consume(); MOZ_ASSERT(style); - aParent.SetCachedInheritedAnonBoxStyle(aAnonBox, *style); + aParent.SetCachedInheritedAnonBoxStyle(aAnonBox, style); } return style.forget(); @@ -482,12 +482,21 @@ ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement, mRawSet.get(), ServoTraversalFlags::Empty).Consume(); } else { + bool cacheable = + !nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) && aParentContext; computedValues = - Servo_ResolvePseudoStyle(aOriginatingElement, - aType, - /* is_probe = */ false, - aParentContext, - mRawSet.get()).Consume(); + cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr; + + if (!computedValues) { + computedValues = Servo_ResolvePseudoStyle(aOriginatingElement, + aType, + /* is_probe = */ false, + aParentContext, + mRawSet.get()).Consume(); + if (cacheable) { + aParentContext->SetCachedLazyPseudoStyle(computedValues); + } + } } MOZ_ASSERT(computedValues); @@ -547,7 +556,7 @@ ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag, mRawSet.get()).Consume(); MOZ_ASSERT(style); if (aParentContext) { - aParentContext->SetCachedInheritedAnonBoxStyle(aPseudoTag, *style); + aParentContext->SetCachedInheritedAnonBoxStyle(aPseudoTag, style); } } @@ -809,13 +818,25 @@ ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement, // aOriginatingElement's styles anyway. MOZ_ASSERT(aType < CSSPseudoElementType::Count); + bool cacheable = + !nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) && aParentContext; + RefPtr computedValues = - Servo_ResolvePseudoStyle(aOriginatingElement, aType, - /* is_probe = */ true, - nullptr, - mRawSet.get()).Consume(); + cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr; if (!computedValues) { - return nullptr; + computedValues = Servo_ResolvePseudoStyle(aOriginatingElement, aType, + /* is_probe = */ true, + nullptr, + mRawSet.get()).Consume(); + if (!computedValues) { + return nullptr; + } + + if (cacheable) { + // NB: We don't need to worry about the before/after handling below + // because those are eager and thus not |cacheable| anyway. + aParentContext->SetCachedLazyPseudoStyle(computedValues); + } } // For :before and :after pseudo-elements, having display: none or no diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index cda1ba704494..6a4170859487 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -15,6 +15,8 @@ // Is this pseudo-element a CSS2 pseudo-element that can be specified // with the single colon syntax (in addition to the double-colon syntax, // which can be used for all pseudo-elements)? +// +// Note: We also rely on this for IsEagerlyCascadedInServo. #define CSS_PSEUDO_ELEMENT_IS_CSS2 (1<<0) // Is this pseudo-element a pseudo-element that can contain other // elements? @@ -85,6 +87,11 @@ public: static bool IsCSS2PseudoElement(nsIAtom *aAtom); + static bool IsEagerlyCascadedInServo(const Type aType) + { + return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_CSS2); + } + #define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \ static nsICSSPseudoElement* _name; #include "nsCSSPseudoElementList.h" From 0863e1a0da1e61877a005c1640717dad7dfa2b48 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 9 Aug 2017 13:03:00 -0500 Subject: [PATCH 057/166] servo: Merge #18026 - Continue cleaning up the traversal entry point machinery (from bholley:continue_traversal_cleanup); r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1388623 Source-Repo: https://github.com/servo/servo Source-Revision: 2b92a7e82d49b8fcead78f91abbabdedf2a569c1 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : e28cb4237e8d72d6fb2b911d3d9a8112e66b65f7 --- servo/components/style/data.rs | 21 +++++++++++++------ .../gecko/pseudo_element_definition.mako.rs | 2 ++ servo/components/style/traversal.rs | 2 +- servo/ports/geckolib/glue.rs | 11 ++++++++++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/servo/components/style/data.rs b/servo/components/style/data.rs index 07870fad7a69..38099cb6eb65 100644 --- a/servo/components/style/data.rs +++ b/servo/components/style/data.rs @@ -69,14 +69,23 @@ impl RestyleData { } /// Clear all the restyle state associated with this element. - fn clear(&mut self) { - *self = Self::new(); + /// + /// FIXME(bholley): The only caller of this should probably just assert that + /// the hint is empty and call clear_flags_and_damage(). + fn clear_restyle_state(&mut self) { + self.clear_restyle_flags_and_damage(); + self.hint = RestyleHint::empty(); } /// Clear restyle flags and damage. - fn clear_flags_and_damage(&mut self) { + /// + /// Note that we don't touch the TRAVERSED_WITHOUT_STYLING bit, which gets + /// set to the correct value on each traversal. There's no reason anyone + /// needs to clear it, and clearing it accidentally mid-traversal could + /// cause incorrect style sharing behavior. + fn clear_restyle_flags_and_damage(&mut self) { self.damage = RestyleDamage::empty(); - self.flags = RestyleFlags::empty(); + self.flags = self.flags & TRAVERSED_WITHOUT_STYLING; } /// Returns whether this element or any ancestor is going to be @@ -420,12 +429,12 @@ impl ElementData { /// Drops any restyle state from the element. pub fn clear_restyle_state(&mut self) { - self.restyle.clear(); + self.restyle.clear_restyle_state(); } /// Drops restyle flags and damage from the element. pub fn clear_restyle_flags_and_damage(&mut self) { - self.restyle.clear_flags_and_damage(); + self.restyle.clear_restyle_flags_and_damage(); } } diff --git a/servo/components/style/gecko/pseudo_element_definition.mako.rs b/servo/components/style/gecko/pseudo_element_definition.mako.rs index fd65de440b42..f11d46f59f39 100644 --- a/servo/components/style/gecko/pseudo_element_definition.mako.rs +++ b/servo/components/style/gecko/pseudo_element_definition.mako.rs @@ -15,6 +15,8 @@ pub enum PseudoElement { % endfor } +/// Important: If you change this, you should also update Gecko's +/// nsCSSPseudoElements::IsEagerlyCascadedInServo. <% EAGER_PSEUDOS = ["Before", "After", "FirstLine", "FirstLetter"] %> <% TREE_PSEUDOS = [pseudo for pseudo in PSEUDOS if pseudo.is_tree_pseudo_element()] %> <% SIMPLE_PSEUDOS = [pseudo for pseudo in PSEUDOS if not pseudo.is_tree_pseudo_element()] %> diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs index a430ad22ad71..c0e795f13a15 100644 --- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -603,7 +603,7 @@ where // data here, since we won't need to perform a post-traversal to pick up // any change hints. if flags.contains(traversal_flags::Forgetful) { - data.clear_restyle_state(); + data.clear_restyle_flags_and_damage(); } // There are two cases when we want to clear the dity descendants bit here diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index a8fadfc202c8..0f66aefe6df7 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -258,6 +258,8 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, let element = GeckoElement(root); + debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags); + // It makes no sense to do an animation restyle when we're restyling // newly-inserted content. if !traversal_flags.contains(traversal_flags::UnstyledChildrenOnly) { @@ -266,6 +268,8 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, element.has_animation_restyle_hints(); if needs_animation_only_restyle { + debug!("Servo_TraverseSubtree doing animation-only restyle (aodd={})", + element.has_animation_only_dirty_descendants()); traverse_subtree(element, raw_data, traversal_flags | traversal_flags::AnimationOnly, @@ -274,6 +278,8 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, } if traversal_flags.for_animation_only() { + debug!("Servo_TraverseSubtree complete (animation-only, aodd={})", + element.has_animation_only_dirty_descendants()); return element.has_animation_only_dirty_descendants() || element.borrow_data().unwrap().restyle.is_restyle(); } @@ -283,6 +289,11 @@ pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed, traversal_flags, unsafe { &*snapshots }); + debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, restyle={:?})", + element.has_dirty_descendants(), + element.has_animation_only_dirty_descendants(), + element.borrow_data().unwrap().restyle); + element.has_dirty_descendants() || element.has_animation_only_dirty_descendants() || element.borrow_data().unwrap().restyle.contains_restyle_data() From 8070fac712d52dbe78ebfddac7a7cf5835a6af63 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 27 Jul 2017 22:07:58 -0700 Subject: [PATCH 058/166] Bug 1388623 - Switch to PreTraverseSync for new-element styling. r=hiro the PreTraverse stuff is all about ticking animations, which isn't something we want to do when we're trying to get styles synchronously in the frame constructor. MozReview-Commit-ID: L6lw4ef4Jdk --- layout/style/ServoStyleSet.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index 83266904354b..b0f6de32ef54 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -898,9 +898,8 @@ ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) void ServoStyleSet::StyleNewSubtree(Element* aRoot) { - MOZ_ASSERT(!aRoot->HasServoData()); - - PreTraverse(); + MOZ_ASSERT(!aRoot->HasServoData(), "Should have called StyleNewChildren"); + PreTraverseSync(); DebugOnly postTraversalRequired = PrepareAndTraverseSubtree(aRoot, ServoTraversalFlags::Empty); @@ -910,7 +909,8 @@ ServoStyleSet::StyleNewSubtree(Element* aRoot) void ServoStyleSet::StyleNewChildren(Element* aParent) { - PreTraverse(); + MOZ_ASSERT(aParent->HasServoData(), "Should have called StyleNewSubtree"); + PreTraverseSync(); PrepareAndTraverseSubtree(aParent, ServoTraversalFlags::UnstyledChildrenOnly); // We can't assert that Servo_TraverseSubtree returns false, since aParent @@ -920,20 +920,17 @@ ServoStyleSet::StyleNewChildren(Element* aParent) void ServoStyleSet::StyleNewlyBoundElement(Element* aElement) { - PreTraverse(); - // In general the element is always styled by the time we're applying XBL // bindings, because we need to style the element to know what the binding // URI is. However, programmatic consumers of the XBL service (like the // XML pretty printer) _can_ apply bindings without having styled the bound // element. We could assert against this and require the callers manually // resolve the style first, but it's easy enough to just handle here. - - ServoTraversalFlags flags = (MOZ_UNLIKELY(!aElement->HasServoData()) - ? ServoTraversalFlags::Empty - : ServoTraversalFlags::UnstyledChildrenOnly); - - PrepareAndTraverseSubtree(aElement, flags); + if (MOZ_LIKELY(aElement->HasServoData())) { + StyleNewChildren(aElement); + } else { + StyleNewSubtree(aElement); + } } void From bac6702aa79da3bbf8306fba97076e20d2c97f93 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 27 Jul 2017 22:18:13 -0700 Subject: [PATCH 059/166] Bug 1388623 - Move the document-root-cache-priming into PreTraverseSync. r=emilio I added this before PreTraverseSync existed, but that's really where it belongs. MozReview-Commit-ID: DZlcH70QbEt --- layout/style/ServoStyleSet.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index b0f6de32ef54..e98b5a699bf7 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -258,6 +258,11 @@ ServoStyleSet::ResolveMappedAttrDeclarationBlocks() void ServoStyleSet::PreTraverseSync() { + // Get the Document's root element to ensure that the cache is valid before + // calling into the (potentially-parallel) Servo traversal, where a cache hit + // is necessary to avoid a data race when updating the cache. + mozilla::Unused << mPresContext->Document()->GetRootElement(); + ResolveMappedAttrDeclarationBlocks(); nsCSSRuleProcessor::InitSystemMetrics(); @@ -332,11 +337,6 @@ ServoStyleSet::PrepareAndTraverseSubtree( AutoRestyleTimelineMarker marker(mPresContext->GetDocShell(), forThrottledAnimationFlush); - // Get the Document's root element to ensure that the cache is valid before - // calling into the (potentially-parallel) Servo traversal, where a cache hit - // is necessary to avoid a data race when updating the cache. - mozilla::Unused << aRoot->OwnerDoc()->GetRootElement(); - MOZ_ASSERT(!StylistNeedsUpdate()); AutoSetInServoTraversal guard(this); From fb45c73178acb402be2a76cbb618f7607d7264c9 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 27 Jul 2017 22:51:27 -0700 Subject: [PATCH 060/166] Bug 1388623 - Use our new traversal flags to avoid doing post-traversal clearing of restyle state. r=emilio MozReview-Commit-ID: E4fqtsQtO9E --- layout/style/ServoStyleSet.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index e98b5a699bf7..825c367a96f2 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -371,24 +371,20 @@ ServoStyleSet::PrepareAndTraverseSubtree( EffectCompositor::AnimationRestyleType::Throttled; if (forReconstruct ? compositor->PreTraverseInSubtree(root, restyleType) : compositor->PreTraverse(restyleType)) { - if (Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags)) { - MOZ_ASSERT(!forReconstruct); - if (isInitial) { - // We're doing initial styling, and the additional animation - // traversal changed the styles that were set by the first traversal. - // This would normally require a post-traversal to update the style - // contexts, and the DOM now has dirty descendant bits and RestyleData - // in expectation of that post-traversal. But since this is actually - // the initial styling, there are no style contexts to update and no - // frames to apply the change hints to, so we don't need to do that - // post-traversal. Instead, just drop this state and tell the caller - // that no post-traversal is required. - MOZ_ASSERT(!postTraversalRequired); - ServoRestyleManager::ClearRestyleStateFromSubtree(root); - } else { - postTraversalRequired = true; - } + if (isInitial) { + // We're doing initial styling, and the additional animation + // traversal will change the styles that were set by the first traversal. + // This would normally require a post-traversal to update the style + // contexts, but since this is actually the initial styling, there are + // no style contexts to update and no frames to apply the change hints to, + // so we just do a forgetful traversal and clear the flags on the way. + aFlags |= ServoTraversalFlags::Forgetful | + ServoTraversalFlags::ClearAnimationOnlyDirtyDescendants; } + + postTraversalRequired = + Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags); + MOZ_ASSERT_IF(isInitial || forReconstruct, !postTraversalRequired); } return postTraversalRequired; From eb938408fcc30c8f703bcd23b1510fc2a4148746 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 15:03:51 -0400 Subject: [PATCH 061/166] Bug 1381435 - Increase the touch_move_tolerance value on desktop, so taps in the tab bar are detected more reliably. r=botond MozReview-Commit-ID: DHKsD4EQK3z --HG-- extra : rebase_source : 9b45969a6cab18ad911d56e978535f1dd46c987a --- gfx/thebes/gfxPrefs.h | 2 +- mobile/android/app/mobile.js | 1 + modules/libpref/init/all.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 9a9add323dee..65dd1cee55dc 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -335,7 +335,7 @@ private: DECL_GFX_PREF(Live, "apz.record_checkerboarding", APZRecordCheckerboarding, bool, false); DECL_GFX_PREF(Live, "apz.test.fails_with_native_injection", APZTestFailsWithNativeInjection, bool, false); DECL_GFX_PREF(Live, "apz.test.logging_enabled", APZTestLoggingEnabled, bool, false); - DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.0); + DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.1); DECL_GFX_PREF(Live, "apz.touch_start_tolerance", APZTouchStartTolerance, float, 1.0f/4.5f); DECL_GFX_PREF(Live, "apz.velocity_bias", APZVelocityBias, float, 0.0f); DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms", APZVelocityRelevanceTime, uint32_t, 150); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 2181c2ac7ca2..9e659314724c 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -562,6 +562,7 @@ pref("apz.fling_friction", "0.004"); pref("apz.fling_stopped_threshold", "0.0"); pref("apz.max_velocity_inches_per_ms", "0.07"); pref("apz.overscroll.enabled", true); +pref("apz.touch_move_tolerance", "0.03"); pref("apz.touch_start_tolerance", "0.06"); pref("layers.progressive-paint", true); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 926888603662..cb4ceb2616a6 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -743,7 +743,7 @@ pref("apz.record_checkerboarding", false); #endif pref("apz.test.logging_enabled", false); pref("apz.touch_start_tolerance", "0.1"); -pref("apz.touch_move_tolerance", "0.03"); +pref("apz.touch_move_tolerance", "0.1"); pref("apz.velocity_bias", "0.0"); pref("apz.velocity_relevance_time_ms", 150); pref("apz.x_skate_highmem_adjust", "0.0"); From e051e64a33351c1b8f71ba073d5c539aef998796 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Tue, 8 Aug 2017 19:48:35 +0200 Subject: [PATCH 062/166] Bug 1386977 - Handle popstate events for page loads. r=automatedtester In case of websites manipulating the browser's history via history.pushState there will be no usual page load events fired. Instead listeners for popstate events have to be used. When such an event occurs we can directly return because the browser will not load the underlying page. This only happens when navigating to another page first, or restarting Firefox. MozReview-Commit-ID: 3PceeYK9Co7 --HG-- extra : rebase_source : 30c162f72279712920a96ebc2076db27d01c41b6 --- .../tests/unit/test_navigation.py | 54 +++++++++++++++++++ .../www/navigation_pushstate.html | 20 +++++++ .../www/navigation_pushstate_target.html | 13 +++++ testing/marionette/listener.js | 4 ++ 4 files changed, 91 insertions(+) create mode 100644 testing/marionette/harness/marionette_harness/www/navigation_pushstate.html create mode 100644 testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py index f3798dcc5a7d..14fbbf7921e0 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py @@ -35,6 +35,7 @@ class BaseNavigationTestCase(WindowManagerMixin, MarionetteTestCase): self.test_page_frameset = self.marionette.absolute_url("frameset.html") self.test_page_insecure = self.fixtures.where_is("test.html", on="https") self.test_page_not_remote = "about:robots" + self.test_page_push_state = self.marionette.absolute_url("navigation_pushstate.html") self.test_page_remote = self.marionette.absolute_url("test.html") self.test_page_slow_resource = self.marionette.absolute_url("slow_resource.html") @@ -213,6 +214,39 @@ class TestNavigate(BaseNavigationTestCase): self.marionette.navigate(test_page.lower()) self.marionette.find_element(By.ID, "foo") + def test_navigate_history_pushstate(self): + target_page = self.marionette.absolute_url("navigation_pushstate_target.html") + + self.marionette.navigate(self.test_page_push_state) + self.marionette.find_element(By.ID, "forward").click() + + # By using pushState() the URL is updated but the target page is not loaded + # and as such the element is not displayed + self.assertEqual(self.marionette.get_url(), target_page) + with self.assertRaises(errors.NoSuchElementException): + self.marionette.find_element(By.ID, "target") + + self.marionette.go_back() + self.assertEqual(self.marionette.get_url(), self.test_page_push_state) + + # The target page still gets not loaded + self.marionette.go_forward() + self.assertEqual(self.marionette.get_url(), target_page) + with self.assertRaises(errors.NoSuchElementException): + self.marionette.find_element(By.ID, "target") + + # Navigating to a different page, and returning to the injected + # page, it will be loaded. + self.marionette.navigate(self.test_page_remote) + self.assertEqual(self.marionette.get_url(), self.test_page_remote) + + self.marionette.go_back() + self.assertEqual(self.marionette.get_url(), target_page) + self.marionette.find_element(By.ID, "target") + + self.marionette.go_back() + self.assertEqual(self.marionette.get_url(), self.test_page_push_state) + @skip_if_mobile("Test file is only located on host machine") def test_navigate_file_url(self): self.marionette.navigate(self.test_page_file_url) @@ -579,6 +613,26 @@ class TestRefresh(BaseNavigationTestCase): self.marionette.refresh() self.assertEqual(image, self.marionette.get_url()) + def test_history_pushstate(self): + target_page = self.marionette.absolute_url("navigation_pushstate_target.html") + + self.marionette.navigate(self.test_page_push_state) + self.marionette.find_element(By.ID, "forward").click() + + # By using pushState() the URL is updated but the target page is not loaded + # and as such the element is not displayed + self.assertEqual(self.marionette.get_url(), target_page) + with self.assertRaises(errors.NoSuchElementException): + self.marionette.find_element(By.ID, "target") + + # Refreshing the target page will trigger a full page load. + self.marionette.refresh() + self.assertEqual(self.marionette.get_url(), target_page) + self.marionette.find_element(By.ID, "target") + + self.marionette.go_back() + self.assertEqual(self.marionette.get_url(), self.test_page_push_state) + def test_timeout_error(self): slow_page = self.marionette.absolute_url("slow?delay=3") diff --git a/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html b/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html new file mode 100644 index 000000000000..8c3fd9c6207a --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html @@ -0,0 +1,20 @@ + + + + + + Navigation by manipulating the browser history + + + + +

Navigate forward

+ + diff --git a/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html b/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html new file mode 100644 index 000000000000..153d0a657fc4 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html @@ -0,0 +1,13 @@ + + + + + + + + +

Pushstate target

+ + diff --git a/testing/marionette/listener.js b/testing/marionette/listener.js index 6e894d49c137..f1117f8e34c7 100644 --- a/testing/marionette/listener.js +++ b/testing/marionette/listener.js @@ -167,6 +167,7 @@ var loadListener = { if (waitForUnloaded) { addEventListener("hashchange", this, false); addEventListener("pagehide", this, false); + addEventListener("popstate", this, false); // The events can only be received when the event listeners are // added to the currently selected frame. @@ -213,6 +214,7 @@ var loadListener = { removeEventListener("hashchange", this); removeEventListener("pagehide", this); + removeEventListener("popstate", this); removeEventListener("DOMContentLoaded", this); removeEventListener("pageshow", this); @@ -262,6 +264,7 @@ var loadListener = { removeEventListener("hashchange", this); removeEventListener("pagehide", this); + removeEventListener("popstate", this); // Now wait until the target page has been loaded addEventListener("DOMContentLoaded", this, false); @@ -269,6 +272,7 @@ var loadListener = { break; case "hashchange": + case "popstate": this.stop(); sendOk(this.command_id); break; From ae1a1c1bc533df7a977755241f95e7b7065d22fc Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Wed, 9 Aug 2017 13:11:47 -0400 Subject: [PATCH 063/166] Bug 1388811 - [try fuzzy] Add ability to run non-interactive fuzzy queries, r=armenzg MozReview-Commit-ID: JojBS8pZHSk --HG-- extra : rebase_source : 9a2e497d7789e3a41a37668eda05168e8301aa5b --- tools/tryselect/mach_commands.py | 10 +++++++--- tools/tryselect/selectors/fuzzy.py | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/tryselect/mach_commands.py b/tools/tryselect/mach_commands.py index 295ba06bfb7e..91e048559bbb 100644 --- a/tools/tryselect/mach_commands.py +++ b/tools/tryselect/mach_commands.py @@ -70,9 +70,13 @@ class TrySelect(MachCommandBase): @SubCommand('try', 'fuzzy', description='Select tasks on try using a fuzzy finder') + @CommandArgument('-q', '--query', metavar='STR', + help="Use the given query instead of entering the selection " + "interface. Equivalent to typing " + "from the interface.") @CommandArgument('-u', '--update', action='store_true', default=False, - help="Update fzf before running") - def try_fuzzy(self, update): + help="Update fzf before running.") + def try_fuzzy(self, *args, **kwargs): """Select which tasks to use with fzf. This selector runs all task labels through a fuzzy finding interface. @@ -116,7 +120,7 @@ class TrySelect(MachCommandBase): ^start 'exact | !ignore fuzzy end$ """ from tryselect.selectors.fuzzy import run_fuzzy_try - return run_fuzzy_try(update) + return run_fuzzy_try(*args, **kwargs) @SubCommand('try', 'syntax', diff --git a/tools/tryselect/selectors/fuzzy.py b/tools/tryselect/selectors/fuzzy.py index 8ddf1b33e1ee..9d894b830ee9 100644 --- a/tools/tryselect/selectors/fuzzy.py +++ b/tools/tryselect/selectors/fuzzy.py @@ -166,7 +166,7 @@ def format_header(): return FZF_HEADER.format(shortcuts=', '.join(shortcuts), t=terminal) -def run_fuzzy_try(update): +def run_fuzzy_try(update=False, query=None): fzf = fzf_bootstrap(update) if not fzf: @@ -188,6 +188,10 @@ def run_fuzzy_try(update): '--preview', 'python -c "print(\\"\\n\\".join(sorted([s.strip(\\"\'\\") for s in \\"{+}\\".split()])))"', # noqa '--preview-window=right:20%', ] + + if query: + cmd.extend(['-f', query]) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE) selected = proc.communicate('\n'.join(all_tasks))[0].splitlines() From 7aa3f6f7e8168aaa0bd9fc3d0a3f56c4c160d9ab Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 9 Aug 2017 12:40:39 -0700 Subject: [PATCH 064/166] Backed out changeset d59ab931a261 (bug 1381435) for windows build failures in gfxPrefs.h a=backout MozReview-Commit-ID: 6xkSA9GmxJh --- gfx/thebes/gfxPrefs.h | 2 +- mobile/android/app/mobile.js | 1 - modules/libpref/init/all.js | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 65dd1cee55dc..9a9add323dee 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -335,7 +335,7 @@ private: DECL_GFX_PREF(Live, "apz.record_checkerboarding", APZRecordCheckerboarding, bool, false); DECL_GFX_PREF(Live, "apz.test.fails_with_native_injection", APZTestFailsWithNativeInjection, bool, false); DECL_GFX_PREF(Live, "apz.test.logging_enabled", APZTestLoggingEnabled, bool, false); - DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.1); + DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.0); DECL_GFX_PREF(Live, "apz.touch_start_tolerance", APZTouchStartTolerance, float, 1.0f/4.5f); DECL_GFX_PREF(Live, "apz.velocity_bias", APZVelocityBias, float, 0.0f); DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms", APZVelocityRelevanceTime, uint32_t, 150); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 9e659314724c..2181c2ac7ca2 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -562,7 +562,6 @@ pref("apz.fling_friction", "0.004"); pref("apz.fling_stopped_threshold", "0.0"); pref("apz.max_velocity_inches_per_ms", "0.07"); pref("apz.overscroll.enabled", true); -pref("apz.touch_move_tolerance", "0.03"); pref("apz.touch_start_tolerance", "0.06"); pref("layers.progressive-paint", true); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index cb4ceb2616a6..926888603662 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -743,7 +743,7 @@ pref("apz.record_checkerboarding", false); #endif pref("apz.test.logging_enabled", false); pref("apz.touch_start_tolerance", "0.1"); -pref("apz.touch_move_tolerance", "0.1"); +pref("apz.touch_move_tolerance", "0.03"); pref("apz.velocity_bias", "0.0"); pref("apz.velocity_relevance_time_ms", 150); pref("apz.x_skate_highmem_adjust", "0.0"); From fdc58801fd3c68d3f7e22f5dbf0222fce2487181 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Wed, 9 Aug 2017 15:03:51 -0400 Subject: [PATCH 065/166] Bug 1381435 - Increase the touch_move_tolerance value on desktop, so taps in the tab bar are detected more reliably. r=botond MozReview-Commit-ID: DHKsD4EQK3z --HG-- extra : rebase_source : c2f9990871281dc96cb97e10b817e27268b74362 --- gfx/thebes/gfxPrefs.h | 2 +- mobile/android/app/mobile.js | 1 + modules/libpref/init/all.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 9a9add323dee..f3be44b97957 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -335,7 +335,7 @@ private: DECL_GFX_PREF(Live, "apz.record_checkerboarding", APZRecordCheckerboarding, bool, false); DECL_GFX_PREF(Live, "apz.test.fails_with_native_injection", APZTestFailsWithNativeInjection, bool, false); DECL_GFX_PREF(Live, "apz.test.logging_enabled", APZTestLoggingEnabled, bool, false); - DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.0); + DECL_GFX_PREF(Live, "apz.touch_move_tolerance", APZTouchMoveTolerance, float, 0.1f); DECL_GFX_PREF(Live, "apz.touch_start_tolerance", APZTouchStartTolerance, float, 1.0f/4.5f); DECL_GFX_PREF(Live, "apz.velocity_bias", APZVelocityBias, float, 0.0f); DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms", APZVelocityRelevanceTime, uint32_t, 150); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 2181c2ac7ca2..9e659314724c 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -562,6 +562,7 @@ pref("apz.fling_friction", "0.004"); pref("apz.fling_stopped_threshold", "0.0"); pref("apz.max_velocity_inches_per_ms", "0.07"); pref("apz.overscroll.enabled", true); +pref("apz.touch_move_tolerance", "0.03"); pref("apz.touch_start_tolerance", "0.06"); pref("layers.progressive-paint", true); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 926888603662..cb4ceb2616a6 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -743,7 +743,7 @@ pref("apz.record_checkerboarding", false); #endif pref("apz.test.logging_enabled", false); pref("apz.touch_start_tolerance", "0.1"); -pref("apz.touch_move_tolerance", "0.03"); +pref("apz.touch_move_tolerance", "0.1"); pref("apz.velocity_bias", "0.0"); pref("apz.velocity_relevance_time_ms", 150); pref("apz.x_skate_highmem_adjust", "0.0"); From f623d605104288fc76f22f90814792f54d6b3e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Wed, 9 Aug 2017 22:05:22 +0200 Subject: [PATCH 066/166] Bug 1386964 - Set default tab height and mark flaky viewport-units-css2-001.html subtests as passing on Linux. r=dholbert MozReview-Commit-ID: 5gLgepyDiaW --HG-- extra : rebase_source : dacd6ced6843e8c819733b05a95eafab853873a9 --- browser/themes/shared/tabs.inc.css | 2 -- .../meta/css/css-values-3/viewport-units-css2-001.html.ini | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index 2dc39d514952..c26c806f5ef8 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -6,12 +6,10 @@ :root { --tab-toolbar-navbar-overlap: 1px; -/* Temporarily using the compact tab strip by default because of bug 1386964: --tab-min-height: 33px; } :root[uidensity=compact] { -*/ --tab-min-height: 29px; } diff --git a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini index eed6261f7ab0..5f8aad9ff46c 100644 --- a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini +++ b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini @@ -7,10 +7,12 @@ if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL [vh length applied to border-top-width] - expected: FAIL + expected: + if os != "linux": FAIL [vmin length applied to border-top-width] - expected: FAIL + expected: + if os != "linux": FAIL [vmax length applied to border-top-width] expected: From 5beff3890ee48586669f5dc678decc2360769138 Mon Sep 17 00:00:00 2001 From: Edouard Oger Date: Thu, 3 Aug 2017 16:10:40 -0400 Subject: [PATCH 067/166] Bug 1372655 - Notify other clients when uploading the local clients record for the first time. r=Grisha MozReview-Commit-ID: HepBI6cbV3J --HG-- extra : rebase_source : 621fd761f51697605c16d16a38d2a77dd98ab6a6 --- .../gecko/background/fxa/FxAccountClient.java | 4 +- .../background/fxa/FxAccountClient20.java | 20 +----- .../sync/stage/SyncClientsEngineStage.java | 68 +++++++++++++++---- .../gecko/fxa/login/MockFxAccountClient.java | 3 +- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient.java b/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient.java index 3807cb277272..adc8ecb9de8a 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient.java @@ -11,8 +11,6 @@ import org.mozilla.gecko.background.fxa.FxAccountClient20.TwoKeys; import org.mozilla.gecko.fxa.devices.FxAccountDevice; import org.mozilla.gecko.sync.ExtendedJSONObject; -import java.util.List; - public interface FxAccountClient { public void accountStatus(String uid, RequestDelegate requestDelegate); public void recoveryEmailStatus(byte[] sessionToken, RequestDelegate requestDelegate); @@ -21,5 +19,5 @@ public interface FxAccountClient { public void registerOrUpdateDevice(byte[] sessionToken, FxAccountDevice device, RequestDelegate requestDelegate); public void destroyDevice(byte[] sessionToken, String deviceId, RequestDelegate requestDelegate); public void deviceList(byte[] sessionToken, RequestDelegate requestDelegate); - public void notifyDevices(byte[] sessionToken, List deviceIds, ExtendedJSONObject payload, Long TTL, RequestDelegate requestDelegate); + public void notifyDevices(byte[] sessionToken, ExtendedJSONObject body, RequestDelegate delegate); } diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient20.java b/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient20.java index b11df5177e75..e35fca9e045a 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient20.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/background/fxa/FxAccountClient20.java @@ -35,7 +35,6 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -898,7 +897,7 @@ public class FxAccountClient20 implements FxAccountClient { } @Override - public void notifyDevices(@NonNull byte[] sessionToken, @NonNull List deviceIds, ExtendedJSONObject payload, Long TTL, RequestDelegate delegate) { + public void notifyDevices(@NonNull byte[] sessionToken, ExtendedJSONObject body, RequestDelegate delegate) { final byte[] tokenId = new byte[32]; final byte[] reqHMACKey = new byte[32]; final byte[] requestKey = new byte[32]; @@ -910,7 +909,6 @@ public class FxAccountClient20 implements FxAccountClient { } final BaseResource resource; - final ExtendedJSONObject body = createNotifyDevicesBody(deviceIds, payload, TTL); try { resource = getBaseResource("account/devices/notify"); } catch (URISyntaxException | UnsupportedEncodingException e) { @@ -931,20 +929,4 @@ public class FxAccountClient20 implements FxAccountClient { post(resource, body); } - - @NonNull - @SuppressWarnings("unchecked") - private ExtendedJSONObject createNotifyDevicesBody(@NonNull List deviceIds, ExtendedJSONObject payload, Long TTL) { - final ExtendedJSONObject body = new ExtendedJSONObject(); - final JSONArray to = new JSONArray(); - to.addAll(deviceIds); - body.put("to", to); - if (payload != null) { - body.put("payload", payload); - } - if (TTL != null) { - body.put("TTL", TTL); - } - return body; - } } diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java index e66db1d21aa4..7951a2ce2325 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java @@ -128,6 +128,9 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage { @Override public void handleRequestSuccess(SyncStorageResponse response) { + final Context context = session.getContext(); + final Account account = FirefoxAccounts.getFirefoxAccount(context); + final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account); // Hang onto the server's last modified timestamp to use // in X-If-Unmodified-Since for upload. @@ -139,9 +142,11 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage { // If we successfully downloaded all records but ours was not one of them // then reset the timestamp. + boolean isFirstLocalClientRecordUpload = false; if (!localAccountGUIDDownloaded) { Logger.info(LOG_TAG, "Local client GUID does not exist on the server. Upload timestamp will be reset."); session.config.persistServerClientRecordTimestamp(0); + isFirstLocalClientRecordUpload = true; } localAccountGUIDDownloaded = false; @@ -176,25 +181,31 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage { // before we actually uploaded the records uploadRemoteRecords(); - // Notify the clients who got their record written - notifyClients(devicesToNotify); + // We will send a push notification later anyway. + if (!isFirstLocalClientRecordUpload) { + // Notify the clients who got their record written + notifyClients(fxAccount, devicesToNotify); + } return; } checkAndUpload(); + if (isFirstLocalClientRecordUpload) { + notifyAllClients(fxAccount); + } } - private void notifyClients(final List devicesToNotify) { - final ExecutorService executor = Executors.newSingleThreadExecutor(); - final Context context = session.getContext(); - final Account account = FirefoxAccounts.getFirefoxAccount(context); - if (account == null) { - Log.e(LOG_TAG, "Can't notify other clients: no account"); - return; - } - final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account); - final ExtendedJSONObject payload = createNotifyDevicesPayload(); + private void notifyClients(@NonNull AndroidFxAccount fxAccount, @NonNull List devicesToNotify) { + final ExtendedJSONObject body = createNotifyClientsBody(devicesToNotify); + notifyClientsHelper(fxAccount, body); + } + private void notifyAllClients(@NonNull AndroidFxAccount fxAccount) { + final ExtendedJSONObject body = createNotifyAllClientsBody(fxAccount.getDeviceId()); + notifyClientsHelper(fxAccount, body); + } + + private void notifyClientsHelper(@NonNull AndroidFxAccount fxAccount, @NonNull ExtendedJSONObject body) { final byte[] sessionToken; try { sessionToken = fxAccount.getState().getSessionToken(); @@ -205,9 +216,10 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage { return; } + final ExecutorService executor = Executors.newSingleThreadExecutor(); // API doc : https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#post-v1accountdevicesnotify final FxAccountClient fxAccountClient = new FxAccountClient20(fxAccount.getAccountServerURI(), executor); - fxAccountClient.notifyDevices(sessionToken, devicesToNotify, payload, NOTIFY_TAB_SENT_TTL_SECS, new FxAccountClient20.RequestDelegate() { + fxAccountClient.notifyDevices(sessionToken, body, new FxAccountClient20.RequestDelegate() { @Override public void handleError(Exception e) { Log.e(LOG_TAG, "Error while notifying devices", e); @@ -220,11 +232,39 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage { @Override public void handleSuccess(ExtendedJSONObject result) { - Log.i(LOG_TAG, devicesToNotify.size() + " devices notified"); + Log.i(LOG_TAG, "Devices notified"); } }); } + @NonNull + @SuppressWarnings("unchecked") + private ExtendedJSONObject createNotifyClientsBody(@NonNull List devicesToNotify) { + final ExtendedJSONObject body = new ExtendedJSONObject(); + final JSONArray to = new JSONArray(); + to.addAll(devicesToNotify); + body.put("to", to); + createNotifyClientsHelper(body); + return body; + } + + @NonNull + @SuppressWarnings("unchecked") + private ExtendedJSONObject createNotifyAllClientsBody(@NonNull String localFxADeviceId) { + final ExtendedJSONObject body = new ExtendedJSONObject(); + body.put("to", "all"); + final JSONArray excluded = new JSONArray(); + excluded.add(localFxADeviceId); + body.put("excluded", excluded); + createNotifyClientsHelper(body); + return body; + } + + private void createNotifyClientsHelper(ExtendedJSONObject body) { + body.put("payload", createNotifyDevicesPayload()); + body.put("TTL", NOTIFY_TAB_SENT_TTL_SECS); + } + @NonNull @SuppressWarnings("unchecked") private ExtendedJSONObject createNotifyDevicesPayload() { diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/fxa/login/MockFxAccountClient.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/fxa/login/MockFxAccountClient.java index 806568dc672f..a84ff974ab3b 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/fxa/login/MockFxAccountClient.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/fxa/login/MockFxAccountClient.java @@ -6,6 +6,7 @@ package org.mozilla.gecko.fxa.login; import android.text.TextUtils; import org.mozilla.gecko.background.fxa.FxAccountClient; +import org.mozilla.gecko.background.fxa.FxAccountClient20; import org.mozilla.gecko.background.fxa.FxAccountClient20.AccountStatusResponse; import org.mozilla.gecko.background.fxa.FxAccountClient20.RequestDelegate; import org.mozilla.gecko.background.fxa.FxAccountClient20.RecoveryEmailStatusResponse; @@ -239,7 +240,7 @@ public class MockFxAccountClient implements FxAccountClient { } @Override - public void notifyDevices(byte[] sessionToken, List deviceIds, ExtendedJSONObject payload, Long TTL, RequestDelegate requestDelegate) { + public void notifyDevices(byte[] sessionToken, ExtendedJSONObject body, RequestDelegate requestDelegate) { requestDelegate.handleSuccess(new ExtendedJSONObject()); } } From 8b3a0e7bc2606aa5ad2fdeaa4a8c82e35d8019c1 Mon Sep 17 00:00:00 2001 From: Chenxia Liu Date: Wed, 9 Aug 2017 12:11:10 -0700 Subject: [PATCH 068/166] Bug 1386906 - Add Pocket keys to build system. r=chmanchester MozReview-Commit-ID: 8fjcSkn1P7P --HG-- extra : rebase_source : 42c608d41e1262d0985dd9f59946a0732a971abc --- mobile/android/base/AppConstants.java.in | 7 +++++++ mobile/android/base/generate_build_config.py | 4 ++++ .../homepanel/topstories/PocketStoriesLoader.java | 15 ++++++++++++++- mobile/android/base/moz.build | 3 +++ mobile/android/base/pocket-api-sandbox.token | 1 + .../mozconfigs/android-aarch64/l10n-nightly | 1 + .../config/mozconfigs/android-api-15/l10n-nightly | 1 + .../config/mozconfigs/android-api-15/nightly | 1 + .../mozconfigs/android-api-15/nightly-old-id | 1 + mobile/android/config/mozconfigs/common | 13 +++++++++++++ mobile/android/moz.configure | 14 ++++++++++++++ toolkit/moz.configure | 2 ++ 12 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 mobile/android/base/pocket-api-sandbox.token diff --git a/mobile/android/base/AppConstants.java.in b/mobile/android/base/AppConstants.java.in index 952343a98512..b5ade2bbfc06 100644 --- a/mobile/android/base/AppConstants.java.in +++ b/mobile/android/base/AppConstants.java.in @@ -337,4 +337,11 @@ public class AppConstants { //#else false; //#endif + + public static final String MOZ_POCKET_API_KEY = +//#ifdef MOZ_ANDROID_POCKET + "@MOZ_POCKET_API_KEY@"; +//#else + null; +//#endif } diff --git a/mobile/android/base/generate_build_config.py b/mobile/android/base/generate_build_config.py index b96d18903bac..64c12ba01ed0 100644 --- a/mobile/android/base/generate_build_config.py +++ b/mobile/android/base/generate_build_config.py @@ -50,6 +50,7 @@ def _defines(): 'MOZ_ANDROID_PWA', 'MOZ_LEANPLUM_SDK_KEY', 'MOZ_LEANPLUM_SDK_CLIENTID', + 'MOZ_ANDROID_POCKET', 'MOZ_ANDROID_SEARCH_ACTIVITY', 'MOZ_CRASHREPORTER', 'MOZ_DEBUG', @@ -112,6 +113,9 @@ def _defines(): DEFINES['MOZ_LEANPLUM_SDK_KEY'] = CONFIG['MOZ_LEANPLUM_SDK_KEY'] DEFINES['MOZ_LEANPLUM_SDK_CLIENTID'] = CONFIG['MOZ_LEANPLUM_SDK_CLIENTID'] + if CONFIG['MOZ_ANDROID_POCKET']: + DEFINES['MOZ_POCKET_API_KEY'] = CONFIG['MOZ_POCKET_API_KEY'] + DEFINES['MOZ_BUILDID'] = open(os.path.join(buildconfig.topobjdir, 'buildid.h')).readline().split()[2] # Set the appropriate version code if not set by MOZ_APP_ANDROID_VERSION_CODE. diff --git a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/topstories/PocketStoriesLoader.java b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/topstories/PocketStoriesLoader.java index 5f9617d9a0dd..0cbeb4962d1a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/topstories/PocketStoriesLoader.java +++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/topstories/PocketStoriesLoader.java @@ -11,6 +11,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.util.Log; +import org.mozilla.gecko.AppConstants; import org.mozilla.gecko.Locales; import org.mozilla.gecko.util.FileUtils; import org.mozilla.gecko.util.ProxySelector; @@ -29,6 +30,14 @@ import java.util.concurrent.TimeUnit; * {@link #loadInBackground()} returns a JSON string of Pocket stories. * * NB: Using AsyncTaskLoader rather than AsyncTask so that loader is tied Activity lifecycle. + * + * Access to Pocket Stories is controlled by a private Pocket API token. + * Add the following to your mozconfig to compile with the Pocket Stories: + * + * export MOZ_ANDROID_POCKET=1 + * ac_add_options --with-pocket-api-keyfile=$topsrcdir/mobile/android/base/pocket-api-sandbox.token + * + * and include the Pocket API token in the token file. */ public class PocketStoriesLoader extends AsyncTaskLoader { @@ -42,7 +51,7 @@ public class PocketStoriesLoader extends AsyncTaskLoader { // Pocket API params and defaults private static final String GLOBAL_ENDPOINT = "https://getpocket.com/v3/firefox/global-recs"; private static final String PARAM_APIKEY = "consumer_key"; - private static final String APIKEY = "KEY_PLACEHOLDER"; // Bug 1386906: Add Pocket keys to builders. + private static final String APIKEY = AppConstants.MOZ_POCKET_API_KEY; private static final String PARAM_COUNT = "count"; private static final int DEFAULT_COUNT = 20; private static final String PARAM_LOCALE = "locale_lang"; @@ -82,6 +91,10 @@ public class PocketStoriesLoader extends AsyncTaskLoader { @Override public String loadInBackground() { + if (APIKEY == null) { + Log.e(LOGTAG, "Missing Pocket API key! See class comment about how to set up a mozconfig."); + return null; + } return makeAPIRequestWithKey(APIKEY); } diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 033e31d2e9bc..b8272bcb1996 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -16,6 +16,9 @@ with Files('*Manifest*'): with Files('adjust-sdk-sandbox.token'): BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support') +with Files('pocket-api-sandbox.token'): + BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support') + with Files('android-services.mozbuild'): BUG_COMPONENT = ('Android Background Services', 'Android Sync') diff --git a/mobile/android/base/pocket-api-sandbox.token b/mobile/android/base/pocket-api-sandbox.token new file mode 100644 index 000000000000..28d14454c380 --- /dev/null +++ b/mobile/android/base/pocket-api-sandbox.token @@ -0,0 +1 @@ +123456789 diff --git a/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly b/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly index f888396f403c..35d9ca226329 100644 --- a/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly +++ b/mobile/android/config/mozconfigs/android-aarch64/l10n-nightly @@ -33,6 +33,7 @@ ac_add_options --without-mozilla-api-keyfile ac_add_options --without-google-api-keyfile ac_add_options --without-adjust-sdk-keyfile ac_add_options --without-leanplum-sdk-keyfile +ac_add_options --without-pocket-api-keyfile # Similarly explicitly disable install tracking for l10n, we'll inherit from en-US export MOZ_INSTALL_TRACKING= diff --git a/mobile/android/config/mozconfigs/android-api-15/l10n-nightly b/mobile/android/config/mozconfigs/android-api-15/l10n-nightly index 48780538b6f4..31895fec9baa 100644 --- a/mobile/android/config/mozconfigs/android-api-15/l10n-nightly +++ b/mobile/android/config/mozconfigs/android-api-15/l10n-nightly @@ -33,6 +33,7 @@ ac_add_options --without-mozilla-api-keyfile ac_add_options --without-google-api-keyfile ac_add_options --without-adjust-sdk-keyfile ac_add_options --without-leanplum-sdk-keyfile +ac_add_options --without-pocket-api-keyfile # Similarly explicitly disable install tracking for l10n, we'll inherit from en-US export MOZ_INSTALL_TRACKING= diff --git a/mobile/android/config/mozconfigs/android-api-15/nightly b/mobile/android/config/mozconfigs/android-api-15/nightly index 339596247b7d..08c2922e7d74 100644 --- a/mobile/android/config/mozconfigs/android-api-15/nightly +++ b/mobile/android/config/mozconfigs/android-api-15/nightly @@ -15,5 +15,6 @@ STRIP_FLAGS="--strip-debug" export MOZILLA_OFFICIAL=1 export MOZ_TELEMETRY_REPORTING=1 export MOZ_ANDROID_MMA=1 +export MOZ_ANDROID_POCKET=1 . "$topsrcdir/mobile/android/config/mozconfigs/common.override" diff --git a/mobile/android/config/mozconfigs/android-api-15/nightly-old-id b/mobile/android/config/mozconfigs/android-api-15/nightly-old-id index c15134542e0a..9c4a563343e0 100644 --- a/mobile/android/config/mozconfigs/android-api-15/nightly-old-id +++ b/mobile/android/config/mozconfigs/android-api-15/nightly-old-id @@ -15,5 +15,6 @@ STRIP_FLAGS="--strip-debug" export MOZILLA_OFFICIAL=1 export MOZ_TELEMETRY_REPORTING=1 export MOZ_ANDROID_MMA=1 +export MOZ_ANDROID_POCKET=1 . "$topsrcdir/mobile/android/config/mozconfigs/common.override" diff --git a/mobile/android/config/mozconfigs/common b/mobile/android/config/mozconfigs/common index 5f9b234c244d..c36efa9561b2 100644 --- a/mobile/android/config/mozconfigs/common +++ b/mobile/android/config/mozconfigs/common @@ -78,6 +78,19 @@ else ac_add_options --with-leanplum-sdk-keyfile="$topsrcdir/mobile/android/base/leanplum-sdk-sandbox.token" fi +# MOZ_ANDROID_POCKET depends on --with-pocket-api-keyfile, and will +# fail if MOZ_ANDROID_POCKET is specified but a keyfile is not. We set a default +# dummy key for non-channel builds, because Pocket is not a critical component. +if test "$MOZ_UPDATE_CHANNEL" = "release" ; then + ac_add_options --with-pocket-api-keyfile=/builds/pocket-api-release.token +elif test "$MOZ_UPDATE_CHANNEL" = "beta" ; then + ac_add_options --with-pocket-api-keyfile=/builds/pocket-api-beta.token +elif test "$MOZ_UPDATE_CHANNEL" = "nightly" ; then + ac_add_options --with-pocket-api-keyfile=/builds/pocket-api-nightly.token +else + ac_add_options --with-pocket-api-keyfile="$topsrcdir/mobile/android/base/pocket-api-sandbox.token" +fi + export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token # Package js shell. diff --git a/mobile/android/moz.configure b/mobile/android/moz.configure index 480f5fb9ba75..31c938e9d62d 100644 --- a/mobile/android/moz.configure +++ b/mobile/android/moz.configure @@ -44,6 +44,13 @@ option(env='MOZ_ANDROID_MMA', set_config('MOZ_ANDROID_MMA', depends_if('MOZ_ANDROID_MMA')(lambda _: True)) +option(env='MOZ_ANDROID_POCKET', + help='Enable Pocket Stories in Activity Stream.', + default=True) + +set_config('MOZ_ANDROID_POCKET', + depends_if('MOZ_ANDROID_POCKET')(lambda _: True)) + project_flag('MOZ_ANDROID_DOWNLOADS_INTEGRATION', help='Enable system download manager on Android', default=True) @@ -159,3 +166,10 @@ def check_android_mma(android_mma, if not leanplum_sdk_keyfile: die('You must specify --with-leanplum-sdk-keyfile=/path/to/keyfile when' ' building with MOZ_ANDROID_MMA=1') + +@depends('MOZ_ANDROID_POCKET', + '--with-pocket-api-keyfile') +def check_android_pocket(android_pocket, pocket_api_keyfile): + if android_pocket and not pocket_api_keyfile: + die('You must specify --with-pocket-api-keyfile=/path/to/keyfile when' + ' building with MOZ_ANDROID_POCKET=1') diff --git a/toolkit/moz.configure b/toolkit/moz.configure index 37d57907756b..82853060e927 100644 --- a/toolkit/moz.configure +++ b/toolkit/moz.configure @@ -560,6 +560,8 @@ simple_keyfile('Adjust SDK') id_and_secret_keyfile('Leanplum SDK') +simple_keyfile('Pocket API') + # Servo integration # ============================================================== option('--enable-stylo', nargs='?', choices=('build',), From f28112f57c609967fe235c365653df9edfb1b812 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Wed, 9 Aug 2017 20:13:42 +0000 Subject: [PATCH 069/166] Bug 1388761 - Update category styling in common.css. r=dao MozReview-Commit-ID: DfDvzw5zVZ8 --HG-- extra : rebase_source : 9ac1070359e11fe2a36b55c65dfd6d5ede6d820a --- .../shared/incontentprefs/preferences.inc.css | 13 ------ .../client/themes/images/debugging-addons.svg | 4 +- .../client/themes/images/debugging-tabs.svg | 7 ++- .../themes/images/debugging-workers.svg | 2 +- .../shared/extensions/extensions.inc.css | 45 +++++++++---------- .../themes/shared/in-content/common.inc.css | 24 +++------- 6 files changed, 36 insertions(+), 59 deletions(-) diff --git a/browser/themes/shared/incontentprefs/preferences.inc.css b/browser/themes/shared/incontentprefs/preferences.inc.css index fe547966eaea..8f117997f0c2 100644 --- a/browser/themes/shared/incontentprefs/preferences.inc.css +++ b/browser/themes/shared/incontentprefs/preferences.inc.css @@ -115,25 +115,12 @@ caption > label { #categories { max-height: 100vh; - background-color: #fafafc; } #categories > scrollbox { overflow-x: hidden !important; } -.category-name { - font-size: 1.45rem; -} - -.category, -.category:hover, -.category[selected] { - background-color: transparent; - border-inline-start: initial; - padding-inline-start: 44px; -} - /** * We want the last category to always have non-0 getBoundingClientRect().bottom * so we can use the value to figure out the max-height of the list in diff --git a/devtools/client/themes/images/debugging-addons.svg b/devtools/client/themes/images/debugging-addons.svg index 8a98d02757a2..d97eedb663a4 100644 --- a/devtools/client/themes/images/debugging-addons.svg +++ b/devtools/client/themes/images/debugging-addons.svg @@ -1,6 +1,6 @@ - - + + diff --git a/devtools/client/themes/images/debugging-tabs.svg b/devtools/client/themes/images/debugging-tabs.svg index 91ad8e9257c4..6e60a038b6b5 100644 --- a/devtools/client/themes/images/debugging-tabs.svg +++ b/devtools/client/themes/images/debugging-tabs.svg @@ -1,3 +1,6 @@ - - + + + diff --git a/devtools/client/themes/images/debugging-workers.svg b/devtools/client/themes/images/debugging-workers.svg index c04c6325231e..baf7be577629 100644 --- a/devtools/client/themes/images/debugging-workers.svg +++ b/devtools/client/themes/images/debugging-workers.svg @@ -1,7 +1,7 @@ - + scrollbox > .scrollbox-innerbox { - border-color: #0095dd; + border-color: var(--in-content-border-focus); } .addon { color: #444; - border-bottom: 1px solid #c1c1c1; + border-bottom: 1px solid var(--in-content-box-border-color); padding: 5px; background-origin: border-box; } @@ -622,10 +621,10 @@ button.warning { } .addon[selected] { - background-color: #fafafa; - color: #333; + background-color: var(--in-content-page-background); + color: var(--in-content-page-color); padding-inline-start: 1px; /* compensate the 4px border */ - border-inline-start: solid 4px #ff9500; + border-inline-start: solid 4px var(--in-content-border-focus); } #addon-list .addon[active="false"] > .content-container > .content-inner-container { @@ -803,9 +802,9 @@ button.warning { #detail-contrib-btn { color: #FFF; text-shadow: none; - border: 1px solid #0095dd; + border: 1px solid transparent; list-style-image: url("chrome://mozapps/skin/extensions/heart.png"); - background-color: #0095dd; + background-color: var(--in-content-primary-button-background); } #detail-contrib-btn .button-icon { @@ -813,13 +812,11 @@ button.warning { } #detail-contrib-btn:not(:active):hover { - border-color: #008acb; - background-color: #008acb; + background-color: var(--in-content-primary-button-background-hover); } #detail-contrib-btn:active:hover { - background-color: #006b9d; - border-color: #006b9d; + background-color: var(--in-content-primary-button-background-active); } #detail-grid { @@ -840,7 +837,7 @@ setting[first-row="true"] { .detail-row, .detail-row-complex, setting { - border-top: 1px solid #c1c1c1; + border-top: 1px solid var(--in-content-box-border-color); -moz-box-align: center; min-height: 35px; line-height: 20px; @@ -906,7 +903,7 @@ setting[type="radio"] > radiogroup { /*** download progress ***/ .download-progress { - border: 1px solid #c1c1c1; + border: 1px solid var(--in-content-box-border-color); border-radius: 2px; background-color: #fbfbfb; width: 200px; @@ -915,7 +912,7 @@ setting[type="radio"] > radiogroup { } .download-progress[mode="undetermined"] { - border-color: #0095dd; + border-color: var(--in-content-border-highlight); } .download-progress .start-cap, @@ -923,7 +920,7 @@ setting[type="radio"] > radiogroup { .download-progress[mode="undetermined"] .end-cap, .download-progress .progress .progress-bar { -moz-appearance: none; - background-color: #0095dd; + background-color: var(--in-content-border-highlight); } .download-progress .progress .progress-bar { diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 8e62da9c1581..f4497e01ac62 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -7,9 +7,9 @@ @namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; *|*:root { - --in-content-page-color: #424e5a; - --in-content-page-background: #fbfbfb; - --in-content-text-color: #333; + --in-content-page-color: #0c0c0d; + --in-content-page-background: #fafafc; + --in-content-text-color: #0c0c0d; --in-content-selected-text: #fff; --in-content-header-border-color: #c8c8c8; --in-content-box-background: #fff; @@ -19,15 +19,11 @@ --in-content-box-border-color: #c1c1c1; --in-content-item-hover: rgba(0,149,221,0.25); --in-content-item-selected: #0a84ff; - --in-content-border-highlight: #ff9500; + --in-content-border-highlight: #0a84ff; --in-content-border-focus: #0a84ff; --in-content-border-color: #c1c1c1; --in-content-category-text: #0c0c0d; - --in-content-category-border-focus: 1px dotted #fff; --in-content-category-text-selected: #0a84ff; - --in-content-category-background: #424f5a; - --in-content-category-background-hover: #5e6972; - --in-content-category-background-active: #343f48; --in-content-tab-color: #424f5a; --in-content-link-color: #0a84ff; --in-content-link-color-hover: #0060df; @@ -647,22 +643,16 @@ xul|*.radio-label-box { -moz-appearance: none; color: var(--in-content-category-text); border-inline-end-width: 0; - padding-inline-start: 15px; + padding-inline-start: 40px; padding-inline-end: 21px; min-height: 40px; transition: background-color 150ms; } -*|*.category:hover { - background-color: var(--in-content-category-background-hover); -} - *|*.category[selected], *|*.category.selected { - background-color: var(--in-content-category-background-active); color: var(--in-content-category-text-selected); - padding-inline-start: 11px; /* compensate the 4px border */ - border-inline-start: solid 4px var(--in-content-border-highlight); + background: none; } *|*#categories[keyboard-navigation="true"]:-moz-focusring > *|*.category[current] { @@ -672,7 +662,7 @@ xul|*.radio-label-box { *|*.category-name { line-height: 22px; - font-size: 1.25rem; + font-size: 1.45rem; padding-bottom: 2px; padding-inline-start: 9px; margin: 0; From 474d5de3006151fcc8f9cd81055f0db1df89bcf3 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 9 Aug 2017 09:05:35 +0900 Subject: [PATCH 070/166] Bug 1388569 - Remove sccache dependencies on jobs that don't use it. r=gps There are essentially four categories of jobs that have dependencies on sccache currently and that shouldn't: - jobs that don't compile anything. They just inherited the dependency because they were using the same tooltool manifests as compiling builds. - jobs that don't use sccache. Ideally, we'd make them use sccache, but things are not currently setup to make that easy, so we'll keep that for later. - jobs that explicitly disable sccache through needs-sccache: false. Like above, ideally, they would use sccache. - jobs that can't use sccache. Those are hazard jobs, that rely on a GCC plugin and AIUI on a global knowledge of the code, which the plugin needs to see. Caching would break that. --HG-- extra : rebase_source : 77455b9f0a58919838c8c64c36aa1db99baf8c7e --- taskcluster/ci/android-stuff/kind.yml | 10 ---------- taskcluster/ci/artifact-build/kind.yml | 1 - taskcluster/ci/build/linux.yml | 1 - taskcluster/ci/hazard/kind.yml | 2 -- taskcluster/ci/spidermonkey/kind.yml | 1 - 5 files changed, 15 deletions(-) diff --git a/taskcluster/ci/android-stuff/kind.yml b/taskcluster/ci/android-stuff/kind.yml index 7e235ccba210..3efb74ea35c1 100644 --- a/taskcluster/ci/android-stuff/kind.yml +++ b/taskcluster/ci/android-stuff/kind.yml @@ -74,8 +74,6 @@ jobs: - "testing/mozharness/configs/builds/releng_sub_android_configs/*gradle_dependencies.py" - "**/*.gradle" - "taskcluster/docker/android-gradle-build/**" - toolchains: - - linux64-sccache android-test: description: "Android armv7 unit tests" @@ -124,8 +122,6 @@ jobs: - - skip-unless-changed - - "mobile/android/base/**" - "mobile/android/tests/background/junit4/**" - toolchains: - - linux64-sccache android-lint: description: "Android lint" @@ -196,8 +192,6 @@ jobs: - "mobile/android/**/*.gradle" - "mobile/android/**/Makefile.in" - "mobile/android/**/moz.build" - toolchains: - - linux64-sccache android-checkstyle: description: "Android checkstyle" @@ -252,8 +246,6 @@ jobs: - "mobile/android/**/*.gradle" - "mobile/android/**/Makefile.in" - "mobile/android/**/moz.build" - toolchains: - - linux64-sccache android-findbugs: description: "Android findbugs" @@ -313,5 +305,3 @@ jobs: - "mobile/android/**/*.gradle" - "mobile/android/**/Makefile.in" - "mobile/android/**/moz.build" - toolchains: - - linux64-sccache diff --git a/taskcluster/ci/artifact-build/kind.yml b/taskcluster/ci/artifact-build/kind.yml index 1a474a2cedda..22b665d1e2e0 100644 --- a/taskcluster/ci/artifact-build/kind.yml +++ b/taskcluster/ci/artifact-build/kind.yml @@ -44,4 +44,3 @@ jobs: toolchains: - linux64-clang - linux64-gcc - - linux64-sccache diff --git a/taskcluster/ci/build/linux.yml b/taskcluster/ci/build/linux.yml index 3778ad481314..583b32e43c07 100644 --- a/taskcluster/ci/build/linux.yml +++ b/taskcluster/ci/build/linux.yml @@ -579,7 +579,6 @@ linux64-ccov/opt: toolchains: - linux64-clang - linux64-gcc - - linux64-sccache linux64-add-on-devel/opt: description: "Linux64 add-on-devel" diff --git a/taskcluster/ci/hazard/kind.yml b/taskcluster/ci/hazard/kind.yml index 11f53544cd08..c5c80dced2a0 100644 --- a/taskcluster/ci/hazard/kind.yml +++ b/taskcluster/ci/hazard/kind.yml @@ -46,7 +46,6 @@ jobs: toolchains: - linux64-clang - linux64-gcc - - linux64-sccache linux64-haz/debug: description: "Browser Hazard Analysis Linux" @@ -68,4 +67,3 @@ jobs: toolchains: - linux64-clang - linux64-gcc - - linux64-sccache diff --git a/taskcluster/ci/spidermonkey/kind.yml b/taskcluster/ci/spidermonkey/kind.yml index f058f7b1d7bb..88ea79476397 100644 --- a/taskcluster/ci/spidermonkey/kind.yml +++ b/taskcluster/ci/spidermonkey/kind.yml @@ -61,7 +61,6 @@ job-defaults: toolchains: - linux64-clang - linux64-gcc - - linux64-sccache jobs: sm-package/opt: From e81f396704f9fdf40e5d1ab88fc7e2a428952cb8 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 9 Aug 2017 09:15:45 +0900 Subject: [PATCH 071/166] Bug 1388572 - Remove toolchain dependencies on artifact builds. r=gps They just inherited the dependencies because they were using the same tooltool manifests as compiling builds. --HG-- extra : rebase_source : 03ee8180e455e01b72016b3132001745b87f78e7 --- taskcluster/ci/artifact-build/kind.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/taskcluster/ci/artifact-build/kind.yml b/taskcluster/ci/artifact-build/kind.yml index 22b665d1e2e0..1cbecf823fb2 100644 --- a/taskcluster/ci/artifact-build/kind.yml +++ b/taskcluster/ci/artifact-build/kind.yml @@ -41,6 +41,3 @@ jobs: tooltool-downloads: public need-xvfb: true keep-artifacts: false - toolchains: - - linux64-clang - - linux64-gcc From e48152158ae2bf7fb4e232df48907ccceabfa757 Mon Sep 17 00:00:00 2001 From: Kirk Steuber Date: Tue, 8 Aug 2017 14:59:49 -0700 Subject: [PATCH 072/166] Bug 1376511 - Handle Browser:Thumbnail:CheckState during idle period r=mconley MozReview-Commit-ID: 6n4nzCqTt0O --HG-- extra : rebase_source : 25f32d6e1ca44d4bb2331d8d745d690d965ed533 --- toolkit/content/browser-child.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 50880cfd0ea6..3b3b3277b554 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -559,9 +559,11 @@ addMessageListener("Browser:Thumbnail:Request", function(aMessage) { * Remote isSafeForCapture request handler for PageThumbs. */ addMessageListener("Browser:Thumbnail:CheckState", function(aMessage) { - let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); - sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { - result + Services.tm.idleDispatchToMainThread(() => { + let result = PageThumbUtils.shouldStoreContentThumbnail(content, docShell); + sendAsyncMessage("Browser:Thumbnail:CheckState:Response", { + result + }); }); }); From 677499eb59a11ed63d6325889e4746a60b694c8f Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Tue, 8 Aug 2017 18:02:31 -0600 Subject: [PATCH 073/166] Bug 1386279 - Renovate Linux sandbox file broker handling of access(). r=gcp 1. X_OK is now allowed, and is limited only by the MAY_ACCESS permission. 2. The actual access() syscall is now used, if access is granted by the broker policy. This fixed bug 1382246, which explains the background. MozReview-Commit-ID: 926429PlBnL --HG-- extra : rebase_source : 6ae54c4c25e1389fa3af75b0bdf727323448294a --- security/sandbox/linux/broker/SandboxBroker.cpp | 14 ++------------ security/sandbox/linux/gtest/TestBroker.cpp | 15 +++++++++++---- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/security/sandbox/linux/broker/SandboxBroker.cpp b/security/sandbox/linux/broker/SandboxBroker.cpp index 3f396d0a4faa..e025654ab4d5 100644 --- a/security/sandbox/linux/broker/SandboxBroker.cpp +++ b/security/sandbox/linux/broker/SandboxBroker.cpp @@ -343,7 +343,7 @@ AllowOperation(int aReqFlags, int aPerms) static bool AllowAccess(int aReqFlags, int aPerms) { - if (aReqFlags & ~(R_OK|W_OK|F_OK)) { + if (aReqFlags & ~(R_OK|W_OK|X_OK|F_OK)) { return false; } int needed = 0; @@ -662,17 +662,7 @@ SandboxBroker::ThreadMain(void) case SANDBOX_FILE_ACCESS: if (permissive || AllowAccess(req.mFlags, perms)) { - // This can't use access() itself because that uses the ruid - // and not the euid. In theory faccessat() with AT_EACCESS - // would work, but Linux doesn't actually implement the - // flags != 0 case; glibc has a hack which doesn't even work - // in this case so it'll ignore the flag, and Bionic just - // passes through the syscall and always ignores the flags. - // - // Instead, because we've already checked the requested - // r/w/x bits against the policy, just return success if the - // file exists and hope that's close enough. - if (stat(pathBuf, (struct stat*)&respBuf) == 0) { + if (access(pathBuf, req.mFlags) == 0) { resp.mError = 0; } else { resp.mError = -errno; diff --git a/security/sandbox/linux/gtest/TestBroker.cpp b/security/sandbox/linux/gtest/TestBroker.cpp index c52ac3ab1cb7..e6f923026a92 100644 --- a/security/sandbox/linux/gtest/TestBroker.cpp +++ b/security/sandbox/linux/gtest/TestBroker.cpp @@ -133,6 +133,8 @@ SandboxBrokerTest::GetPolicy() const policy->AddPath(MAY_READ | MAY_WRITE, "/tmp", AddAlways); policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublu", AddAlways); policy->AddPath(MAY_READ | MAY_WRITE | MAY_CREATE, "/tmp/blublublu", AddAlways); + // This should be non-writable by the user running the test: + policy->AddPath(MAY_READ | MAY_WRITE, "/etc", AddAlways); return Move(policy); } @@ -206,6 +208,14 @@ TEST_F(SandboxBrokerTest, Access) EXPECT_EQ(-EACCES, Access("/proc/self", R_OK)); EXPECT_EQ(-EACCES, Access("/proc/self/stat", F_OK)); + + EXPECT_EQ(0, Access("/tmp", X_OK)); + EXPECT_EQ(0, Access("/tmp", R_OK|X_OK)); + EXPECT_EQ(0, Access("/tmp", R_OK|W_OK|X_OK)); + EXPECT_EQ(0, Access("/proc/self", X_OK)); + + EXPECT_EQ(0, Access("/etc", R_OK|X_OK)); + EXPECT_EQ(-EACCES, Access("/etc", W_OK)); } TEST_F(SandboxBrokerTest, Stat) @@ -257,10 +267,7 @@ TEST_F(SandboxBrokerTest, Chmod) close(fd); // Set read only. SandboxBroker enforces 0600 mode flags. ASSERT_EQ(0, Chmod("/tmp/blublu", S_IRUSR)); - // SandboxBroker doesn't use real access(), it just checks against - // the policy. So it can't see the change in permisions here. - // This won't work: - // EXPECT_EQ(-EACCES, Access("/tmp/blublu", W_OK)); + EXPECT_EQ(-EACCES, Access("/tmp/blublu", W_OK)); statstruct realStat; EXPECT_EQ(0, statsyscall("/tmp/blublu", &realStat)); EXPECT_EQ((mode_t)S_IRUSR, realStat.st_mode & 0777); From 726ce851426723a09ac08d6b188375d028e6fd73 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 9 Aug 2017 09:22:43 +0900 Subject: [PATCH 074/166] Bug 1388573 - Imply needs-sccache from toolchain dependencies. r=dustin After bug 1388569 and bug 1388572, all jobs that have needs-sccache set have a dependency on either linux64-sccache or win64-sccache, and vice-versa. Which means they are now redundant, and one should imply the other. --HG-- extra : rebase_source : ae72f67ccf2da7ba645416b8be4d10687005d01a --- taskcluster/ci/build/linux.yml | 1 - taskcluster/ci/static-analysis/kind.yml | 1 - taskcluster/ci/valgrind/kind.yml | 1 - taskcluster/taskgraph/transforms/build.py | 1 - taskcluster/taskgraph/transforms/toolchain.py | 3 +++ 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/taskcluster/ci/build/linux.yml b/taskcluster/ci/build/linux.yml index 583b32e43c07..b7c213f9d310 100644 --- a/taskcluster/ci/build/linux.yml +++ b/taskcluster/ci/build/linux.yml @@ -554,7 +554,6 @@ linux64-ccov/opt: index: product: firefox job-name: linux64-ccov-opt - needs-sccache: false treeherder: platform: linux64-ccov/opt symbol: tc(B) diff --git a/taskcluster/ci/static-analysis/kind.yml b/taskcluster/ci/static-analysis/kind.yml index 59fddd0af753..5d3020145d0c 100644 --- a/taskcluster/ci/static-analysis/kind.yml +++ b/taskcluster/ci/static-analysis/kind.yml @@ -20,7 +20,6 @@ job-defaults: symbol: S kind: build tier: 1 - needs-sccache: true jobs: linux64-st-an/debug: diff --git a/taskcluster/ci/valgrind/kind.yml b/taskcluster/ci/valgrind/kind.yml index 10195414fbf6..cd37eb5c1871 100644 --- a/taskcluster/ci/valgrind/kind.yml +++ b/taskcluster/ci/valgrind/kind.yml @@ -30,7 +30,6 @@ jobs: max-run-time: 72000 env: TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/linux64/releng.manifest" - needs-sccache: true run: using: mozharness actions: [get-secrets build valgrind-test] diff --git a/taskcluster/taskgraph/transforms/build.py b/taskcluster/taskgraph/transforms/build.py index d21b9b069c3a..705b1e1148ae 100644 --- a/taskcluster/taskgraph/transforms/build.py +++ b/taskcluster/taskgraph/transforms/build.py @@ -20,7 +20,6 @@ def set_defaults(config, jobs): for job in jobs: job['treeherder'].setdefault('kind', 'build') job['treeherder'].setdefault('tier', 1) - job.setdefault('needs-sccache', True) _, worker_os = worker_type_implementation(job['worker-type']) worker = job.setdefault('worker', {}) if worker_os == "linux": diff --git a/taskcluster/taskgraph/transforms/toolchain.py b/taskcluster/taskgraph/transforms/toolchain.py index 5b658b0899b6..bf6fea2a87c2 100644 --- a/taskcluster/taskgraph/transforms/toolchain.py +++ b/taskcluster/taskgraph/transforms/toolchain.py @@ -80,6 +80,9 @@ def use_toolchains(config, jobs): t, f)) filenames[f] = t + if t.endswith('-sccache'): + job['needs-sccache'] = True + if toolchains: job.setdefault('dependencies', {}).update( ('toolchain-%s' % t, 'toolchain-%s' % t) From 66d4d80b032c7980b908b2e38be1dc6ae099f785 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 9 Aug 2017 18:45:16 +0900 Subject: [PATCH 075/166] Bug 1388681 - Disable -Wformat-security where -Wformat is disabled. r=bwc --HG-- extra : rebase_source : b303f70c2900b8dff538083a6b406545170356c2 --- media/mtransport/third_party/nICEr/nicer.gyp | 2 ++ media/mtransport/third_party/nrappkit/nrappkit.gyp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/media/mtransport/third_party/nICEr/nicer.gyp b/media/mtransport/third_party/nICEr/nicer.gyp index f11aec4a93f7..84628de2d78f 100644 --- a/media/mtransport/third_party/nICEr/nicer.gyp +++ b/media/mtransport/third_party/nICEr/nicer.gyp @@ -164,6 +164,7 @@ '-Wno-strict-prototypes', '-Wmissing-prototypes', '-Wno-format', + '-Wno-format-security', ], 'defines' : [ 'HAVE_LIBM=1', @@ -212,6 +213,7 @@ '-Wno-strict-prototypes', '-Wmissing-prototypes', '-Wno-format', + '-Wno-format-security', ], 'defines' : [ 'LINUX', diff --git a/media/mtransport/third_party/nrappkit/nrappkit.gyp b/media/mtransport/third_party/nrappkit/nrappkit.gyp index f67f3bb8ccaa..614a6c7ac017 100644 --- a/media/mtransport/third_party/nrappkit/nrappkit.gyp +++ b/media/mtransport/third_party/nrappkit/nrappkit.gyp @@ -160,6 +160,7 @@ '-Wno-strict-prototypes', '-Wmissing-prototypes', '-Wno-format', + '-Wno-format-security', ], 'defines' : [ 'HAVE_LIBM=1', @@ -207,6 +208,7 @@ '-Wno-strict-prototypes', '-Wmissing-prototypes', '-Wno-format', + '-Wno-format-security', ], 'defines' : [ 'LINUX', From 966527f5aa8670c189fde54ac3fde368f9db58d3 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 1 Aug 2017 16:17:22 +0200 Subject: [PATCH 076/166] Bug 1382968 - Move console actor helper modules to a dedicated folder. r=jryans MozReview-Commit-ID: 6l1kcHFglDf --HG-- rename : devtools/server/actors/utils/webconsole-listeners.js => devtools/server/actors/webconsole/listeners.js rename : devtools/server/actors/utils/moz.build => devtools/server/actors/webconsole/moz.build rename : devtools/server/actors/utils/webconsole-utils.js => devtools/server/actors/webconsole/utils.js rename : devtools/server/actors/utils/webconsole-worker-listeners.js => devtools/server/actors/webconsole/worker-listeners.js extra : rebase_source : 5760bfc4de183e74b6eb8a511006c770121f24b9 --- devtools/client/shared/developer-toolbar.js | 2 +- devtools/server/actors/addon.js | 2 +- devtools/server/actors/moz.build | 1 + devtools/server/actors/utils/moz.build | 3 --- devtools/server/actors/webconsole.js | 16 ++++++++-------- .../listeners.js} | 2 +- devtools/server/actors/webconsole/moz.build | 11 +++++++++++ .../webconsole-utils.js => webconsole/utils.js} | 0 .../worker-listeners.js} | 0 .../shared/tests/unit/test_console_filtering.js | 2 +- .../webconsole/test/test_cached_messages.html | 2 +- .../test/test_commands_registration.html | 2 +- 12 files changed, 26 insertions(+), 17 deletions(-) rename devtools/server/actors/{utils/webconsole-listeners.js => webconsole/listeners.js} (99%) create mode 100644 devtools/server/actors/webconsole/moz.build rename devtools/server/actors/{utils/webconsole-utils.js => webconsole/utils.js} (100%) rename devtools/server/actors/{utils/webconsole-worker-listeners.js => webconsole/worker-listeners.js} (100%) diff --git a/devtools/client/shared/developer-toolbar.js b/devtools/client/shared/developer-toolbar.js index 37e0b9d12bf4..833a7148d832 100644 --- a/devtools/client/shared/developer-toolbar.js +++ b/devtools/client/shared/developer-toolbar.js @@ -25,7 +25,7 @@ loader.lazyGetter(this, "prefBranch", function () { loader.lazyRequireGetter(this, "gcliInit", "devtools/shared/gcli/commands/index"); loader.lazyRequireGetter(this, "util", "gcli/util/util"); -loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/utils/webconsole-listeners", true); +loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/listeners", true); loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true); loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true); loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants"); diff --git a/devtools/server/actors/addon.js b/devtools/server/actors/addon.js index 3520c06f1a2e..1b458d8b3b59 100644 --- a/devtools/server/actors/addon.js +++ b/devtools/server/actors/addon.js @@ -9,7 +9,7 @@ var Services = require("Services"); var { ActorPool } = require("devtools/server/actors/common"); var { TabSources } = require("./utils/TabSources"); var makeDebugger = require("./utils/make-debugger"); -var { ConsoleAPIListener } = require("devtools/server/actors/utils/webconsole-listeners"); +var { ConsoleAPIListener } = require("devtools/server/actors/webconsole/listeners"); var DevToolsUtils = require("devtools/shared/DevToolsUtils"); var { assert, update } = DevToolsUtils; diff --git a/devtools/server/actors/moz.build b/devtools/server/actors/moz.build index 783720b7c913..5e0e704a9048 100644 --- a/devtools/server/actors/moz.build +++ b/devtools/server/actors/moz.build @@ -7,6 +7,7 @@ DIRS += [ 'highlighters', 'utils', + 'webconsole', ] DevToolsModules( diff --git a/devtools/server/actors/utils/moz.build b/devtools/server/actors/utils/moz.build index 6bacf0ac6e0e..979a0324ea12 100644 --- a/devtools/server/actors/utils/moz.build +++ b/devtools/server/actors/utils/moz.build @@ -15,7 +15,4 @@ DevToolsModules( 'stack.js', 'TabSources.js', 'walker-search.js', - 'webconsole-listeners.js', - 'webconsole-utils.js', - 'webconsole-worker-listeners.js', ) diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index 16d3697451fe..ec929e2555b4 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -25,20 +25,20 @@ loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webcons loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true); loader.lazyRequireGetter(this, "Parser", "resource://devtools/shared/Parser.jsm", true); loader.lazyRequireGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm", true); -loader.lazyRequireGetter(this, "addWebConsoleCommands", "devtools/server/actors/utils/webconsole-utils", true); -loader.lazyRequireGetter(this, "CONSOLE_WORKER_IDS", "devtools/server/actors/utils/webconsole-utils", true); -loader.lazyRequireGetter(this, "WebConsoleUtils", "devtools/server/actors/utils/webconsole-utils", true); +loader.lazyRequireGetter(this, "addWebConsoleCommands", "devtools/server/actors/webconsole/utils", true); +loader.lazyRequireGetter(this, "CONSOLE_WORKER_IDS", "devtools/server/actors/webconsole/utils", true); +loader.lazyRequireGetter(this, "WebConsoleUtils", "devtools/server/actors/webconsole/utils", true); loader.lazyRequireGetter(this, "EnvironmentActor", "devtools/server/actors/environment", true); // Overwrite implemented listeners for workers so that we don't attempt // to load an unsupported module. if (isWorker) { - loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/utils/webconsole-worker-listeners", true); - loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/utils/webconsole-worker-listeners", true); + loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/webconsole/worker-listeners", true); + loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/worker-listeners", true); } else { - loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/utils/webconsole-listeners", true); - loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/utils/webconsole-listeners", true); - loader.lazyRequireGetter(this, "ConsoleReflowListener", "devtools/server/actors/utils/webconsole-listeners", true); + loader.lazyRequireGetter(this, "ConsoleAPIListener", "devtools/server/actors/webconsole/listeners", true); + loader.lazyRequireGetter(this, "ConsoleServiceListener", "devtools/server/actors/webconsole/listeners", true); + loader.lazyRequireGetter(this, "ConsoleReflowListener", "devtools/server/actors/webconsole/listeners", true); } /** diff --git a/devtools/server/actors/utils/webconsole-listeners.js b/devtools/server/actors/webconsole/listeners.js similarity index 99% rename from devtools/server/actors/utils/webconsole-listeners.js rename to devtools/server/actors/webconsole/listeners.js index bf9082937923..94d8d051b5c9 100644 --- a/devtools/server/actors/utils/webconsole-listeners.js +++ b/devtools/server/actors/webconsole/listeners.js @@ -8,7 +8,7 @@ const {Cc, Ci, components} = require("chrome"); const {isWindowIncluded} = require("devtools/shared/layout/utils"); const Services = require("Services"); const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm"); -const {CONSOLE_WORKER_IDS, WebConsoleUtils} = require("devtools/server/actors/utils/webconsole-utils"); +const {CONSOLE_WORKER_IDS, WebConsoleUtils} = require("devtools/server/actors/webconsole/utils"); XPCOMUtils.defineLazyServiceGetter(this, "swm", diff --git a/devtools/server/actors/webconsole/moz.build b/devtools/server/actors/webconsole/moz.build new file mode 100644 index 000000000000..d6e64676952c --- /dev/null +++ b/devtools/server/actors/webconsole/moz.build @@ -0,0 +1,11 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DevToolsModules( + 'listeners.js', + 'utils.js', + 'worker-listeners.js', +) diff --git a/devtools/server/actors/utils/webconsole-utils.js b/devtools/server/actors/webconsole/utils.js similarity index 100% rename from devtools/server/actors/utils/webconsole-utils.js rename to devtools/server/actors/webconsole/utils.js diff --git a/devtools/server/actors/utils/webconsole-worker-listeners.js b/devtools/server/actors/webconsole/worker-listeners.js similarity index 100% rename from devtools/server/actors/utils/webconsole-worker-listeners.js rename to devtools/server/actors/webconsole/worker-listeners.js diff --git a/devtools/shared/tests/unit/test_console_filtering.js b/devtools/shared/tests/unit/test_console_filtering.js index 5c7b2dadff8e..d8cf8b262081 100644 --- a/devtools/shared/tests/unit/test_console_filtering.js +++ b/devtools/shared/tests/unit/test_console_filtering.js @@ -4,7 +4,7 @@ "use strict"; const { console, ConsoleAPI } = require("resource://gre/modules/Console.jsm"); -const { ConsoleAPIListener } = require("devtools/server/actors/utils/webconsole-listeners"); +const { ConsoleAPIListener } = require("devtools/server/actors/webconsole/listeners"); const Services = require("Services"); var seenMessages = 0; diff --git a/devtools/shared/webconsole/test/test_cached_messages.html b/devtools/shared/webconsole/test/test_cached_messages.html index c5121d2b7a75..e14348c7ecee 100644 --- a/devtools/shared/webconsole/test/test_cached_messages.html +++ b/devtools/shared/webconsole/test/test_cached_messages.html @@ -97,7 +97,7 @@ function doConsoleCalls() {

>::AtRule, PreciseParseError<'i, E>> where P: AtRuleParser<'i, Error = E> { @@ -434,7 +445,8 @@ fn parse_at_rule<'i: 't, 't, P, E>(start_position: SourcePosition, name: CowRcSt Ok(&Token::Semicolon) | Err(_) => Ok(rule), Ok(&Token::CurlyBracketBlock) => Err(PreciseParseError { error: ParseError::Basic(BasicParseError::UnexpectedToken(Token::CurlyBracketBlock)), - span: start_position..input.position(), + slice: input.slice_from(start.position()), + location: start.source_location(), }), Ok(_) => unreachable!() } @@ -446,16 +458,19 @@ fn parse_at_rule<'i: 't, 't, P, E>(start_position: SourcePosition, name: CowRcSt parse_nested_block::<'i, 't, _, _, _>(input, move |input| parser.parse_block(prelude, input)) .map_err(|e| PreciseParseError { error: e, - span: start_position..input.position(), + slice: input.slice_from(start.position()), + location: start.source_location(), }) } Ok(&Token::Semicolon) => Err(PreciseParseError { error: ParseError::Basic(BasicParseError::UnexpectedToken(Token::Semicolon)), - span: start_position..input.position() + slice: input.slice_from(start.position()), + location: start.source_location(), }), Err(e) => Err(PreciseParseError { error: ParseError::Basic(e), - span: start_position..input.position(), + slice: input.slice_from(start.position()), + location: start.source_location(), }), Ok(_) => unreachable!() } @@ -468,7 +483,8 @@ fn parse_at_rule<'i: 't, 't, P, E>(start_position: SourcePosition, name: CowRcSt parse_nested_block::<'i, 't, _, _, _>(input, move |input| parser.parse_block(prelude, input)) .map_err(|e| PreciseParseError { error: e, - span: start_position..input.position(), + slice: input.slice_from(start.position()), + location: start.source_location(), }) } _ => unreachable!() @@ -482,7 +498,8 @@ fn parse_at_rule<'i: 't, 't, P, E>(start_position: SourcePosition, name: CowRcSt }; Err(PreciseParseError { error: error, - span: start_position..end_position, + slice: input.slice(start.position()..end_position), + location: start.source_location(), }) } } diff --git a/third_party/rust/cssparser/src/size_of_tests.rs b/third_party/rust/cssparser/src/size_of_tests.rs index 13effc90d897..b352bdf7a26e 100644 --- a/third_party/rust/cssparser/src/size_of_tests.rs +++ b/third_party/rust/cssparser/src/size_of_tests.rs @@ -31,7 +31,17 @@ macro_rules! size_of_test { } } -// These assume 64-bit +// Some of these assume 64-bit size_of_test!(token, Token, 32); size_of_test!(std_cow_str, Cow<'static, str>, 32); size_of_test!(cow_rc_str, CowRcStr, 16); + +size_of_test!(tokenizer, ::tokenizer::Tokenizer, 40); +size_of_test!(parser_input, ::parser::ParserInput, 112); +size_of_test!(parser, ::parser::Parser, 16); +size_of_test!(source_position, ::SourcePosition, 8); +size_of_test!(parser_state, ::ParserState, 24); + +size_of_test!(basic_parse_error, ::BasicParseError, 40); +size_of_test!(parse_error_lower_bound, ::ParseError<()>, 48); +size_of_test!(precise_parse_error_lower_bound, ::PreciseParseError<()>, 72); diff --git a/third_party/rust/cssparser/src/tests.rs b/third_party/rust/cssparser/src/tests.rs index 4f10fcf10e87..6d58856e596f 100644 --- a/third_party/rust/cssparser/src/tests.rs +++ b/third_party/rust/cssparser/src/tests.rs @@ -467,28 +467,40 @@ fn serialize_rgba_two_digit_float_if_roundtrips() { #[test] fn line_numbers() { - let mut input = ParserInput::new("foo bar\nbaz\r\n\n\"a\\\r\nb\""); + let mut input = ParserInput::new(concat!( + "fo\\30\r\n", + "0o bar/*\n", + "*/baz\r\n", + "\n", + "url(\r\n", + " u \r\n", + ")\"a\\\r\n", + "b\"" + )); let mut input = Parser::new(&mut input); assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 0 }); - assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("foo".into()))); - assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 3 }); + assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("fo00o".into()))); + assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 2 }); assert_eq!(input.next_including_whitespace(), Ok(&Token::WhiteSpace(" "))); - assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 4 }); - assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("bar".into()))); - assert_eq!(input.current_source_location(), SourceLocation { line: 0, column: 7 }); - assert_eq!(input.next_including_whitespace(), Ok(&Token::WhiteSpace("\n"))); - assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 0 }); - assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("baz".into()))); assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 3 }); - let position = input.position(); + assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("bar".into()))); + assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 6 }); + assert_eq!(input.next_including_whitespace_and_comments(), Ok(&Token::Comment("\n"))); + assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 2 }); + assert_eq!(input.next_including_whitespace(), Ok(&Token::Ident("baz".into()))); + assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 5 }); + let state = input.state(); assert_eq!(input.next_including_whitespace(), Ok(&Token::WhiteSpace("\r\n\n"))); - assert_eq!(input.current_source_location(), SourceLocation { line: 3, column: 0 }); + assert_eq!(input.current_source_location(), SourceLocation { line: 4, column: 0 }); - assert_eq!(input.source_location(position), SourceLocation { line: 1, column: 3 }); + assert_eq!(state.source_location(), SourceLocation { line: 2, column: 5 }); + + assert_eq!(input.next_including_whitespace(), Ok(&Token::UnquotedUrl("u".into()))); + assert_eq!(input.current_source_location(), SourceLocation { line: 6, column: 1 }); assert_eq!(input.next_including_whitespace(), Ok(&Token::QuotedString("ab".into()))); - assert_eq!(input.current_source_location(), SourceLocation { line: 4, column: 2 }); + assert_eq!(input.current_source_location(), SourceLocation { line: 7, column: 2 }); assert!(input.next_including_whitespace().is_err()); } @@ -701,21 +713,21 @@ impl<'i> DeclarationParser<'i> for JsonParser { let mut value = vec![]; let mut important = false; loop { - let start_position = input.position(); + let start = input.state(); if let Ok(mut token) = input.next_including_whitespace().map(|t| t.clone()) { // Hack to deal with css-parsing-tests assuming that // `!important` in the middle of a declaration value is OK. // This can never happen per spec // (even CSS Variables forbid top-level `!`) if token == Token::Delim('!') { - input.reset(start_position); + input.reset(&start); if parse_important(input).is_ok() { if input.is_exhausted() { important = true; break } } - input.reset(start_position); + input.reset(&start); token = input.next_including_whitespace().unwrap().clone(); } value.push(one_component_value_to_json(token, input)); diff --git a/third_party/rust/cssparser/src/tokenizer.rs b/third_party/rust/cssparser/src/tokenizer.rs index 2fdfc0245fb6..4ea462e8c421 100644 --- a/third_party/rust/cssparser/src/tokenizer.rs +++ b/third_party/rust/cssparser/src/tokenizer.rs @@ -5,11 +5,11 @@ // https://drafts.csswg.org/css-syntax/#tokenization use std::ops::Range; -use std::cell::Cell; use std::char; use std::ascii::AsciiExt; use std::i32; +use parser::ParserState; use cow_rc_str::CowRcStr; use self::Token::*; @@ -205,8 +205,8 @@ pub struct Tokenizer<'a> { input: &'a str, /// Counted in bytes, not code points. From 0. position: usize, - /// Cache for `source_location()` - last_known_source_location: Cell<(SourcePosition, SourceLocation)>, + current_line_start_position: usize, + current_line_number: u32, var_functions: SeenStatus, viewport_percentages: SeenStatus, } @@ -222,11 +222,16 @@ enum SeenStatus { impl<'a> Tokenizer<'a> { #[inline] pub fn new(input: &str) -> Tokenizer { + Tokenizer::with_first_line_number(input, 0) + } + + #[inline] + pub fn with_first_line_number(input: &str, first_line_number: u32) -> Tokenizer { Tokenizer { input: input, position: 0, - last_known_source_location: Cell::new((SourcePosition(0), - SourceLocation { line: 0, column: 0 })), + current_line_start_position: 0, + current_line_number: first_line_number, var_functions: SeenStatus::DontCare, viewport_percentages: SeenStatus::DontCare, } @@ -288,8 +293,28 @@ impl<'a> Tokenizer<'a> { } #[inline] - pub fn reset(&mut self, new_position: SourcePosition) { - self.position = new_position.0; + pub fn current_source_location(&self) -> SourceLocation { + SourceLocation { + line: self.current_line_number, + column: (self.position - self.current_line_start_position) as u32, + } + } + + #[inline] + pub fn state(&self) -> ParserState { + ParserState { + position: self.position, + current_line_start_position: self.current_line_start_position, + current_line_number: self.current_line_number, + at_start_of: None, + } + } + + #[inline] + pub fn reset(&mut self, state: &ParserState) { + self.position = state.position; + self.current_line_start_position = state.current_line_start_position; + self.current_line_number = state.current_line_number; } #[inline] @@ -302,12 +327,6 @@ impl<'a> Tokenizer<'a> { &self.input[range.start.0..range.end.0] } - #[inline] - pub fn current_source_location(&self) -> SourceLocation { - let position = SourcePosition(self.position); - self.source_location(position) - } - pub fn current_source_line(&self) -> &'a str { let current = self.position; let start = self.input[0..current] @@ -319,37 +338,6 @@ impl<'a> Tokenizer<'a> { &self.input[start..end] } - pub fn source_location(&self, position: SourcePosition) -> SourceLocation { - let target = position.0; - let mut location; - let mut position; - let (SourcePosition(last_known_position), last_known_location) = - self.last_known_source_location.get(); - if target >= last_known_position { - position = last_known_position; - location = last_known_location; - } else { - // For now we’re only traversing the source *forwards* to count newlines. - // So if the requested position is before the last known one, - // start over from the beginning. - position = 0; - location = SourceLocation { line: 0, column: 0 }; - } - let mut source = &self.input[position..target]; - while let Some(newline_position) = source.find(|c| matches!(c, '\n' | '\r' | '\x0C')) { - let offset = newline_position + - if source[newline_position..].starts_with("\r\n") { 2 } else { 1 }; - source = &source[offset..]; - position += offset; - location.line += 1; - location.column = 0; - } - debug_assert!(position <= target); - location.column += (target - position) as u32; - self.last_known_source_location.set((SourcePosition(target), location)); - location - } - #[inline] pub fn next_byte(&self) -> Option { if self.is_eof() { @@ -391,6 +379,14 @@ impl<'a> Tokenizer<'a> { self.input[self.position..].chars().next().unwrap() } + fn seen_newline(&mut self, is_cr: bool) { + if is_cr && self.next_byte() == Some(/* LF */ b'\n') { + return + } + self.current_line_start_position = self.position; + self.current_line_number += 1; + } + #[inline] fn has_newline_at(&self, offset: usize) -> bool { self.position + offset < self.input.len() && @@ -410,15 +406,15 @@ impl<'a> Tokenizer<'a> { } } - +/// A position from the start of the input, counted in UTF-8 bytes. #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)] -pub struct SourcePosition(usize); +pub struct SourcePosition(pub(crate) usize); /// The line and column number for a given position within the input. #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub struct SourceLocation { - /// The line number, starting at 0 for the first line. + /// The line number, starting at 0 for the first line, unless `with_first_line_number` was used. pub line: u32, /// The column number within a line, starting at 0 for first the character of the line. @@ -432,16 +428,14 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, ()> { } let b = tokenizer.next_byte_unchecked(); let token = match_byte! { b, - b'\t' | b'\n' | b' ' | b'\r' | b'\x0C' => { - let start_position = tokenizer.position(); - tokenizer.advance(1); - while !tokenizer.is_eof() { - match tokenizer.next_byte_unchecked() { - b' ' | b'\t' | b'\n' | b'\r' | b'\x0C' => tokenizer.advance(1), - _ => break, - } - } - WhiteSpace(tokenizer.slice_from(start_position)) + b' ' | b'\t' => { + consume_whitespace(tokenizer, false, false) + }, + b'\n' | b'\x0C' => { + consume_whitespace(tokenizer, true, false) + }, + b'\r' => { + consume_whitespace(tokenizer, true, true) }, b'"' => { consume_string(tokenizer, false) }, b'#' => { @@ -513,21 +507,7 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, ()> { } b'/' => { if tokenizer.starts_with(b"/*") { - tokenizer.advance(2); // consume "/*" - let start_position = tokenizer.position(); - let content; - match tokenizer.input[tokenizer.position..].find("*/") { - Some(offset) => { - tokenizer.advance(offset); - content = tokenizer.slice_from(start_position); - tokenizer.advance(2); - } - None => { - tokenizer.position = tokenizer.input.len(); - content = tokenizer.slice_from(start_position); - } - } - Comment(content) + Comment(consume_comment(tokenizer)) } else { tokenizer.advance(1); Delim('/') @@ -585,6 +565,64 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, ()> { } +fn consume_whitespace<'a>(tokenizer: &mut Tokenizer<'a>, newline: bool, is_cr: bool) -> Token<'a> { + let start_position = tokenizer.position(); + tokenizer.advance(1); + if newline { + tokenizer.seen_newline(is_cr) + } + while !tokenizer.is_eof() { + let b = tokenizer.next_byte_unchecked(); + match_byte! { b, + b' ' | b'\t' => { + tokenizer.advance(1); + } + b'\n' | b'\x0C' => { + tokenizer.advance(1); + tokenizer.seen_newline(false); + } + b'\r' => { + tokenizer.advance(1); + tokenizer.seen_newline(true); + } + _ => { + break + } + } + } + WhiteSpace(tokenizer.slice_from(start_position)) +} + + +fn consume_comment<'a>(tokenizer: &mut Tokenizer<'a>) -> &'a str { + tokenizer.advance(2); // consume "/*" + let start_position = tokenizer.position(); + while !tokenizer.is_eof() { + match_byte! { tokenizer.next_byte_unchecked(), + b'*' => { + let end_position = tokenizer.position(); + tokenizer.advance(1); + if tokenizer.next_byte() == Some(b'/') { + tokenizer.advance(1); + return tokenizer.slice(start_position..end_position) + } + } + b'\n' | b'\x0C' => { + tokenizer.advance(1); + tokenizer.seen_newline(false); + } + b'\r' => { + tokenizer.advance(1); + tokenizer.seen_newline(true); + } + _ => { + tokenizer.advance(1); + } + } + } + tokenizer.slice_from(start_position) +} + fn consume_string<'a>(tokenizer: &mut Tokenizer<'a>, single_quote: bool) -> Token<'a> { match consume_quoted_string(tokenizer, single_quote) { Ok(value) => QuotedString(value), @@ -661,12 +699,19 @@ fn consume_quoted_string<'a>(tokenizer: &mut Tokenizer<'a>, single_quote: bool) if !tokenizer.is_eof() { match tokenizer.next_byte_unchecked() { // Escaped newline - b'\n' | b'\x0C' => tokenizer.advance(1), + b'\n' | b'\x0C' => { + tokenizer.advance(1); + tokenizer.seen_newline(false); + } b'\r' => { tokenizer.advance(1); if tokenizer.next_byte() == Some(b'\n') { tokenizer.advance(1); } + // `is_cr = true` is useful to skip \r when the next iteration + // of a loop will call `seen_newline` again for the following \n. + // In this case we’re consuming both in this iteration, so passing `false`. + tokenizer.seen_newline(false); } // This pushes one well-formed code point _ => consume_escape_and_write(tokenizer, &mut string_bytes) @@ -933,24 +978,57 @@ unsafe fn from_utf8_release_unchecked(string_bytes: Vec) -> String { fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, ()> { // This is only called after "url(", so the current position is a code point boundary. - for (offset, c) in tokenizer.input[tokenizer.position..].bytes().enumerate() { - match_byte! { c, - b' ' | b'\t' | b'\n' | b'\r' | b'\x0C' => {}, + let start_position = tokenizer.position; + let from_start = &tokenizer.input[tokenizer.position..]; + let mut newlines = 0; + let mut last_newline = 0; + let mut found_printable_char = false; + let mut iter = from_start.bytes().enumerate(); + loop { + let (offset, b) = match iter.next() { + Some(item) => item, + None => { + tokenizer.position = tokenizer.input.len(); + break + } + }; + match_byte! { b, + b' ' | b'\t' => {}, + b'\n' | b'\x0C' => { + newlines += 1; + last_newline = offset; + } + b'\r' => { + if from_start.as_bytes().get(offset + 1) != Some(&b'\n') { + newlines += 1; + last_newline = offset; + } + } b'"' | b'\'' => { return Err(()) }, // Do not advance b')' => { tokenizer.advance(offset + 1); - return Ok(UnquotedUrl("".into())); + break } _ => { tokenizer.advance(offset); - // This function only consumed ASCII (whitespace) bytes, - // so the current position is a code point boundary. - return Ok(consume_unquoted_url_internal(tokenizer)) + found_printable_char = true; + break } } } - tokenizer.position = tokenizer.input.len(); - return Ok(UnquotedUrl("".into())); + + if newlines > 0 { + tokenizer.current_line_number += newlines; + tokenizer.current_line_start_position = start_position + last_newline + 1; + } + + if found_printable_char { + // This function only consumed ASCII (whitespace) bytes, + // so the current position is a code point boundary. + return Ok(consume_unquoted_url_internal(tokenizer)) + } else { + return Ok(UnquotedUrl("".into())) + } fn consume_unquoted_url_internal<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> { // This function is only called with start_pos at a code point boundary. @@ -963,7 +1041,6 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, match_byte! { tokenizer.next_byte_unchecked(), b' ' | b'\t' | b'\n' | b'\r' | b'\x0C' => { let value = tokenizer.slice_from(start_pos); - tokenizer.advance(1); return consume_url_end(tokenizer, start_pos, value.into()) } b')' => { @@ -986,7 +1063,7 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, break } _ => { - tokenizer.consume_byte(); + tokenizer.advance(1); } } } @@ -995,6 +1072,7 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, b' ' | b'\t' | b'\n' | b'\r' | b'\x0C' => { // string_bytes is well-formed UTF-8, see other comments. let string = unsafe { from_utf8_release_unchecked(string_bytes) }.into(); + tokenizer.position -= 1; return consume_url_end(tokenizer, start_pos, string) } b')' => { @@ -1032,8 +1110,16 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, -> Token<'a> { while !tokenizer.is_eof() { match_byte! { tokenizer.consume_byte(), - b' ' | b'\t' | b'\n' | b'\r' | b'\x0C' => {}, - b')' => { break }, + b')' => { + break + } + b' ' | b'\t' => {} + b'\n' | b'\x0C' => { + tokenizer.seen_newline(false); + } + b'\r' => { + tokenizer.seen_newline(true); + } _ => { return consume_bad_url(tokenizer, start_pos); } @@ -1046,12 +1132,20 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result, // Consume up to the closing ) while !tokenizer.is_eof() { match_byte! { tokenizer.consume_byte(), - b')' => { break }, + b')' => { + break + } b'\\' => { if matches!(tokenizer.next_byte(), Some(b')') | Some(b'\\')) { tokenizer.advance(1); // Skip an escaped ')' or '\' } } + b'\n' | b'\x0C' => { + tokenizer.seen_newline(false); + } + b'\r' => { + tokenizer.seen_newline(true); + } _ => {}, } } @@ -1092,15 +1186,22 @@ fn consume_escape(tokenizer: &mut Tokenizer) -> char { b'0'...b'9' | b'A'...b'F' | b'a'...b'f' => { let (c, _) = consume_hex_digits(tokenizer); if !tokenizer.is_eof() { - match tokenizer.next_byte_unchecked() { - b' ' | b'\t' | b'\n' | b'\x0C' => tokenizer.advance(1), + match_byte! { tokenizer.next_byte_unchecked(), + b' ' | b'\t' => { + tokenizer.advance(1) + } + b'\n' | b'\x0C' => { + tokenizer.advance(1); + tokenizer.seen_newline(false) + } b'\r' => { tokenizer.advance(1); if !tokenizer.is_eof() && tokenizer.next_byte_unchecked() == b'\n' { tokenizer.advance(1); } + tokenizer.seen_newline(false) } - _ => () + _ => {} } } static REPLACEMENT_CHAR: char = '\u{FFFD}'; diff --git a/third_party/rust/cssparser/src/unicode_range.rs b/third_party/rust/cssparser/src/unicode_range.rs index 0e1b58acdaf5..af0eda2eed98 100644 --- a/third_party/rust/cssparser/src/unicode_range.rs +++ b/third_party/rust/cssparser/src/unicode_range.rs @@ -68,12 +68,12 @@ fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseErro parse_question_marks(input) } Token::Number { .. } => { - let after_number = input.position(); + let after_number = input.state(); match input.next_including_whitespace() { Ok(&Token::Delim('?')) => parse_question_marks(input), Ok(&Token::Dimension { .. }) => {} Ok(&Token::Number { .. }) => {} - _ => input.reset(after_number) + _ => input.reset(&after_number) } } t => return Err(BasicParseError::UnexpectedToken(t)) @@ -84,11 +84,11 @@ fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseErro /// Consume as many '?' as possible fn parse_question_marks(input: &mut Parser) { loop { - let position = input.position(); + let start = input.state(); match input.next_including_whitespace() { Ok(&Token::Delim('?')) => {} _ => { - input.reset(position); + input.reset(&start); return } } diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index 6ccee380f19d..6779e3f9acb4 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -232,7 +232,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -384,7 +384,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -843,7 +843,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -945,7 +945,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -992,7 +992,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.19.0", ] @@ -1299,7 +1299,7 @@ dependencies = [ "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79" "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6" -"checksum cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c89e2d77451da8a55f1f2fcaf7eb86c32da9296890c6a474c7e4047f2429b2f4" +"checksum cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5464ebae36626f28254b60d1abbba951417383192bcea65578b40fbec1a47" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1" "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index 5c4fbf5e8afe..a6054a2d4866 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -230,7 +230,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.18.2" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -382,7 +382,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -830,7 +830,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -932,7 +932,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -979,7 +979,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.19.0", ] @@ -1286,7 +1286,7 @@ dependencies = [ "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79" "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6" -"checksum cssparser 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c89e2d77451da8a55f1f2fcaf7eb86c32da9296890c6a474c7e4047f2429b2f4" +"checksum cssparser 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5464ebae36626f28254b60d1abbba951417383192bcea65578b40fbec1a47" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1" "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" From 759140610ec61241235a49bc43b7915849ba7a91 Mon Sep 17 00:00:00 2001 From: Jonathan Guillotte-Blouin Date: Mon, 17 Jul 2017 13:29:21 -0700 Subject: [PATCH 100/166] Bug 1381186 - open/close stub dialog on (show/abort)Payment. r=MattN MozReview-Commit-ID: K3YyFlIttjD --HG-- extra : rebase_source : 97639e91e6d35ade1fa11cea5ae923fa522bc44a --- modules/libpref/init/all.js | 1 + .../payments/content/paymentRequest.xhtml | 2 +- .../components/payments/paymentUIService.js | 34 ++++++++++++++++++- toolkit/components/payments/payments.manifest | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 75d5b371885f..dfa075bcbcbb 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5728,6 +5728,7 @@ pref("dom.timeout.max_consecutive_callbacks_ms", 4); // Use this preference to house "Payment Request API" during development pref("dom.payments.request.enabled", false); +pref("dom.payments.loglevel", "Warn"); #ifdef FUZZING pref("fuzzing.enabled", false); diff --git a/toolkit/components/payments/content/paymentRequest.xhtml b/toolkit/components/payments/content/paymentRequest.xhtml index f14bf0a7b506..a552a53ed1d0 100644 --- a/toolkit/components/payments/content/paymentRequest.xhtml +++ b/toolkit/components/payments/content/paymentRequest.xhtml @@ -11,7 +11,7 @@

- +
diff --git a/toolkit/components/payments/paymentUIService.js b/toolkit/components/payments/paymentUIService.js index 04c816d9c217..a0656551d092 100644 --- a/toolkit/components/payments/paymentUIService.js +++ b/toolkit/components/payments/paymentUIService.js @@ -9,25 +9,57 @@ const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; const DIALOG_URL = "chrome://payments/content/paymentRequest.xhtml"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "paymentSrv", "@mozilla.org/dom/payments/payment-request-service;1", "nsIPaymentRequestService"); -function PaymentUIService() {} +function defineLazyLogGetter(scope, logPrefix) { + XPCOMUtils.defineLazyGetter(scope, "log", () => { + let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {}); + return new ConsoleAPI({ + maxLogLevelPref: "dom.payments.loglevel", + prefix: logPrefix, + }); + }); +} + +function PaymentUIService() { + defineLazyLogGetter(this, "Payment UI Service"); + paymentSrv.setTestingUIService(this); + this.log.debug("constructor"); +} PaymentUIService.prototype = { classID: Components.ID("{01f8bd55-9017-438b-85ec-7c15d2b35cdc}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIService]), + REQUEST_ID_PREFIX: "paymentRequest-", showPayment(requestId) { + this.log.debug("showPayment"); + let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser"); + chromeWindow.openDialog(DIALOG_URL, + `${this.REQUEST_ID_PREFIX}${requestId}`, + "modal,dialog,centerscreen"); }, abortPayment(requestId) { + this.log.debug(`abortPayment: ${requestId}`); let abortResponse = Cc["@mozilla.org/dom/payments/payment-abort-action-response;1"] .createInstance(Ci.nsIPaymentAbortActionResponse); abortResponse.init(requestId, Ci.nsIPaymentActionResponse.ABORT_SUCCEEDED); + + let enu = Services.wm.getEnumerator(null); + let win; + while ((win = enu.getNext())) { + if (win.name == `${this.REQUEST_ID_PREFIX}${requestId}`) { + this.log.debug(`closing: ${win.name}`); + win.close(); + break; + } + } paymentSrv.respondPayment(abortResponse.QueryInterface(Ci.nsIPaymentActionResponse)); }, diff --git a/toolkit/components/payments/payments.manifest b/toolkit/components/payments/payments.manifest index 5d66076a538b..9100389bb6c1 100644 --- a/toolkit/components/payments/payments.manifest +++ b/toolkit/components/payments/payments.manifest @@ -1,2 +1,3 @@ component {01f8bd55-9017-438b-85ec-7c15d2b35cdc} paymentUIService.js contract @mozilla.org/dom/payments/payment-ui-service;1 {01f8bd55-9017-438b-85ec-7c15d2b35cdc} +category profile-after-change PaymentUIService @mozilla.org/dom/payments/payment-ui-service;1 From 2f52051a3ee6f8a7804254f8d84709c32d0ded0f Mon Sep 17 00:00:00 2001 From: Jonathan Guillotte-Blouin Date: Tue, 18 Jul 2017 18:12:27 -0700 Subject: [PATCH 101/166] Bug 1381186 - add show/abort chrome test. r=MattN MozReview-Commit-ID: I6Umm24nNvA --HG-- extra : rebase_source : 8c6b5c08280a5bd1da971718b90cdf818ad0ec65 --- browser/installer/package-manifest.in | 2 + .../payments/test/browser/blank_page.html | 10 ++++ .../payments/test/browser/browser.ini | 6 +++ .../test/browser/browser_show_dialog.js | 31 ++++++++++++ .../components/payments/test/browser/head.js | 49 +++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 toolkit/components/payments/test/browser/blank_page.html create mode 100644 toolkit/components/payments/test/browser/browser_show_dialog.js create mode 100644 toolkit/components/payments/test/browser/head.js diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 8a388f2c5b9d..6b15efc98683 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -399,8 +399,10 @@ @RESPATH@/components/nsSearchService.js @RESPATH@/components/nsSearchSuggestions.js @RESPATH@/components/nsSidebar.js +#ifdef NIGHTLY_BUILD @RESPATH@/components/payments.manifest @RESPATH@/components/paymentUIService.js +#endif @RESPATH@/components/passwordmgr.manifest @RESPATH@/components/nsLoginInfo.js @RESPATH@/components/nsLoginManager.js diff --git a/toolkit/components/payments/test/browser/blank_page.html b/toolkit/components/payments/test/browser/blank_page.html new file mode 100644 index 000000000000..2a42a20e6e1a --- /dev/null +++ b/toolkit/components/payments/test/browser/blank_page.html @@ -0,0 +1,10 @@ + + + + + Blank page + + + BLANK PAGE + + diff --git a/toolkit/components/payments/test/browser/browser.ini b/toolkit/components/payments/test/browser/browser.ini index 9c7215410b0d..3809ebfcec13 100644 --- a/toolkit/components/payments/test/browser/browser.ini +++ b/toolkit/components/payments/test/browser/browser.ini @@ -1,4 +1,10 @@ [DEFAULT] +head = head.js + support-files = + blank_page.html [browser_request_summary.js] +[browser_show_dialog.js] +# Bug 1365964 - Payment Request isn't implemented for non-e10s +skip-if = !e10s diff --git a/toolkit/components/payments/test/browser/browser_show_dialog.js b/toolkit/components/payments/test/browser/browser_show_dialog.js new file mode 100644 index 000000000000..869104b5d8b8 --- /dev/null +++ b/toolkit/components/payments/test/browser/browser_show_dialog.js @@ -0,0 +1,31 @@ +"use strict"; + +const methodData = [{ + supportedMethods: ["basic-card"], +}]; +const details = { + total: { + label: "Total due", + amount: { currency: "USD", value: "60.00" }, + }, +}; + +add_task(async function test_show_abort_dialog() { + await BrowserTestUtils.withNewTab({ + gBrowser, + url: BLANK_PAGE_URL, + }, async browser => { + // start by creating a PaymentRequest, and show it + await ContentTask.spawn(browser, {methodData, details}, ContentTasks.createAndShowRequest); + + // get a reference to the UI dialog and the requestId + let win = await getDialogWindow(); + let requestId = requestIdForWindow(win); + ok(requestId, "requestId should be defined"); + ok(!win.closed, "dialog should not be closed"); + + // abort the payment request + await ContentTask.spawn(browser, null, async() => content.rq.abort()); + ok(win.closed, "dialog should be closed"); + }); +}); diff --git a/toolkit/components/payments/test/browser/head.js b/toolkit/components/payments/test/browser/head.js new file mode 100644 index 000000000000..e4cbbcfdcaea --- /dev/null +++ b/toolkit/components/payments/test/browser/head.js @@ -0,0 +1,49 @@ +"use strict"; + +/* eslint + "no-unused-vars": ["error", { + vars: "local", + args: "none", + varsIgnorePattern: "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$", + }], +*/ + +const REQUEST_ID_PREFIX = "paymentRequest-"; +const BLANK_PAGE_URL = "https://example.com/browser/toolkit/components/" + + "payments/test/browser/blank_page.html"; +const PREF_PAYMENT_ENABLED = "dom.payments.request.enabled"; + + +async function getDialogWindow() { + let win; + await BrowserTestUtils.waitForCondition(() => { + win = Services.wm.getMostRecentWindow(null); + return win.name.startsWith(REQUEST_ID_PREFIX); + }, "payment dialog should be the most recent"); + + return win; +} + +function requestIdForWindow(window) { + let windowName = window.name; + + return windowName.startsWith(REQUEST_ID_PREFIX) ? + windowName.replace(REQUEST_ID_PREFIX, "") : // returns suffix, which is the requestId + null; +} + +/** + * Common content tasks functions to be used with ContentTask.spawn. + */ +let ContentTasks = { + createAndShowRequest: async ({methodData, details, options}) => { + let rq = new content.PaymentRequest(methodData, details, options); + content.rq = rq; // assign it so we can retrieve it later + rq.show(); + }, +}; + + +add_task(async function setup_head() { + await SpecialPowers.pushPrefEnv({set: [[PREF_PAYMENT_ENABLED, true]]}); +}); From 90c5853da05f1afb4e2c4062bfd7c8904e599398 Mon Sep 17 00:00:00 2001 From: Connor Brewster Date: Wed, 9 Aug 2017 17:22:28 -0500 Subject: [PATCH 102/166] servo: Merge #17935 - Custom element upgrades (from cbrewster:ce_upgrades); r=jdm --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: a087fee4b4daa76c7e1677b0adae512fb6c87d04 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : bc88c8fe15f2b1838da65c9a5d0d1b007c036fe6 --- servo/components/script/dom/attr.rs | 2 +- .../dom/bindings/codegen/CodegenRust.py | 7 +- .../script/dom/bindings/interface.rs | 51 +++-- servo/components/script/dom/create.rs | 45 ++++- .../script/dom/customelementregistry.rs | 176 ++++++++++++++++-- servo/components/script/dom/document.rs | 12 +- servo/components/script/dom/element.rs | 46 ++++- servo/components/script/dom/node.rs | 15 +- servo/components/script/script_thread.rs | 17 +- servo/tests/unit/script/size_of.rs | 8 +- 10 files changed, 311 insertions(+), 68 deletions(-) diff --git a/servo/components/script/dom/attr.rs b/servo/components/script/dom/attr.rs index bf2ecd6e9105..3ce627b46775 100644 --- a/servo/components/script/dom/attr.rs +++ b/servo/components/script/dom/attr.rs @@ -188,7 +188,7 @@ impl Attr { if owner.get_custom_element_definition().is_some() { let reaction = CallbackReaction::AttributeChanged(name, Some(old_value), Some(new_value), namespace); - ScriptThread::enqueue_callback_reaction(owner, reaction); + ScriptThread::enqueue_callback_reaction(owner, reaction, None); } assert!(Some(owner) == self.owner().r()); diff --git a/servo/components/script/dom/bindings/codegen/CodegenRust.py b/servo/components/script/dom/bindings/codegen/CodegenRust.py index 482b713e10c3..7f97868a3788 100644 --- a/servo/components/script/dom/bindings/codegen/CodegenRust.py +++ b/servo/components/script/dom/bindings/codegen/CodegenRust.py @@ -5377,7 +5377,12 @@ let result = match result { }, }; -JS_SetPrototype(cx, result.reflector().get_jsobject(), prototype.handle()); +rooted!(in(cx) let mut element = result.reflector().get_jsobject().get()); +if !JS_WrapObject(cx, element.handle_mut()) { + return false; +} + +JS_SetPrototype(cx, element.handle(), prototype.handle()); (result).to_jsval(cx, args.rval()); return true; diff --git a/servo/components/script/dom/bindings/interface.rs b/servo/components/script/dom/bindings/interface.rs index 887a62f11eb9..63658b3f0f93 100644 --- a/servo/components/script/dom/bindings/interface.rs +++ b/servo/components/script/dom/bindings/interface.rs @@ -80,7 +80,8 @@ use dom::bindings::guard::Guard; use dom::bindings::js::Root; use dom::bindings::utils::{DOM_PROTOTYPE_SLOT, ProtoOrIfaceArray, get_proto_or_iface_array}; use dom::create::create_native_html_element; -use dom::element::{Element, ElementCreator}; +use dom::customelementregistry::ConstructionStackEntry; +use dom::element::{CustomElementState, Element, ElementCreator}; use dom::htmlelement::HTMLElement; use dom::window::Window; use html5ever::LocalName; @@ -281,24 +282,44 @@ pub unsafe fn html_constructor(window: &Window, call_args: &CallArgs) -> Fall } } - // Step 8.1 - let name = QualName::new(None, ns!(html), definition.local_name.clone()); - let element = if definition.is_autonomous() { - Root::upcast(HTMLElement::new(name.local, None, &*document)) - } else { - create_native_html_element(name, None, &*document, ElementCreator::ScriptCreated) - }; + let entry = definition.construction_stack.borrow().last().cloned(); + match entry { + // Step 8 + None => { + // Step 8.1 + let name = QualName::new(None, ns!(html), definition.local_name.clone()); + let element = if definition.is_autonomous() { + Root::upcast(HTMLElement::new(name.local, None, &*document)) + } else { + create_native_html_element(name, None, &*document, ElementCreator::ScriptCreated) + }; - // Step 8.2 is performed in the generated caller code. + // Step 8.2 is performed in the generated caller code. - // TODO: Step 8.3 - 8.4 - // Set the element's custom element state and definition. + // Step 8.3 + element.set_custom_element_state(CustomElementState::Custom); - // Step 8.5 - Root::downcast(element).ok_or(Error::InvalidState) + // Step 8.4 + element.set_custom_element_definition(definition.clone()); - // TODO: Steps 9-13 - // Custom element upgrades are not implemented yet, so these steps are unnecessary. + // Step 8.5 + Root::downcast(element).ok_or(Error::InvalidState) + }, + // Step 9 + Some(ConstructionStackEntry::Element(element)) => { + // Step 11 is performed in the generated caller code. + + // Step 12 + let mut construction_stack = definition.construction_stack.borrow_mut(); + construction_stack.pop(); + construction_stack.push(ConstructionStackEntry::AlreadyConstructedMarker); + + // Step 13 + Root::downcast(element).ok_or(Error::InvalidState) + }, + // Step 10 + Some(ConstructionStackEntry::AlreadyConstructedMarker) => Err(Error::InvalidState), + } } pub fn push_new_element_queue() { diff --git a/servo/components/script/dom/create.rs b/servo/components/script/dom/create.rs index 5f03a3adb982..922757593f35 100644 --- a/servo/components/script/dom/create.rs +++ b/servo/components/script/dom/create.rs @@ -5,8 +5,9 @@ use dom::bindings::error::{report_pending_exception, throw_dom_exception}; use dom::bindings::js::Root; use dom::bindings::reflector::DomObject; +use dom::customelementregistry::{is_valid_custom_element_name, upgrade_element}; use dom::document::Document; -use dom::element::{CustomElementCreationMode, Element, ElementCreator}; +use dom::element::{CustomElementCreationMode, CustomElementState, Element, ElementCreator}; use dom::globalscope::GlobalScope; use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlappletelement::HTMLAppletElement; @@ -80,6 +81,7 @@ use dom::htmlvideoelement::HTMLVideoElement; use dom::svgsvgelement::SVGSVGElement; use html5ever::{LocalName, Prefix, QualName}; use js::jsapi::JSAutoCompartment; +use script_thread::ScriptThread; use servo_config::prefs::PREFS; fn create_svg_element(name: QualName, @@ -121,13 +123,18 @@ fn create_html_element(name: QualName, assert!(name.ns == ns!(html)); // Step 4 - let definition = document.lookup_custom_element_definition(name.local.clone(), is); + let definition = document.lookup_custom_element_definition(&name.ns, &name.local, is.as_ref()); if let Some(definition) = definition { if definition.is_autonomous() { match mode { - // TODO: Handle asynchronous CE creation. Relies on CE upgrades. - CustomElementCreationMode::Asynchronous => {}, + CustomElementCreationMode::Asynchronous => { + let result = Root::upcast::( + HTMLElement::new(name.local.clone(), prefix.clone(), document)); + result.set_custom_element_state(CustomElementState::Undefined); + ScriptThread::enqueue_upgrade_reaction(&*result, definition); + return result; + }, CustomElementCreationMode::Synchronous => { let local_name = name.local.clone(); return match definition.create_element(document, prefix.clone()) { @@ -148,20 +155,40 @@ fn create_html_element(name: QualName, } // Step 6.1.2 - Root::upcast(HTMLUnknownElement::new(local_name, prefix, document)) + let element = Root::upcast::( + HTMLUnknownElement::new(local_name, prefix, document)); + element.set_custom_element_state(CustomElementState::Failed); + element }, }; }, } } else { + // Steps 5.1-5.2 let element = create_native_html_element(name, prefix, document, creator); element.set_is(definition.name.clone()); - // TODO: Enqueue custom element upgrade + element.set_custom_element_state(CustomElementState::Undefined); + match mode { + // Step 5.3 + CustomElementCreationMode::Synchronous => + upgrade_element(definition, &*element), + // Step 5.4 + CustomElementCreationMode::Asynchronous => + ScriptThread::enqueue_upgrade_reaction(&*element, definition), + } return element; } } - create_native_html_element(name, prefix, document, creator) + // Steps 7.1-7.2 + let result = create_native_html_element(name.clone(), prefix, document, creator); + + // Step 7.3 + if is_valid_custom_element_name(&*name.local) || is.is_some() { + result.set_custom_element_state(CustomElementState::Undefined); + } + + result } pub fn create_native_html_element(name: QualName, @@ -184,6 +211,7 @@ pub fn create_native_html_element(name: QualName, // This is a big match, and the IDs for inline-interned atoms are not very structured. // Perhaps we should build a perfect hash from those IDs instead. + // https://html.spec.whatwg.org/multipage/#elements-in-the-dom match name.local { local_name!("a") => make!(HTMLAnchorElement), local_name!("abbr") => make!(HTMLElement), @@ -326,7 +354,8 @@ pub fn create_native_html_element(name: QualName, local_name!("video") => make!(HTMLVideoElement), local_name!("wbr") => make!(HTMLElement), local_name!("xmp") => make!(HTMLPreElement), - _ => make!(HTMLUnknownElement), + _ if is_valid_custom_element_name(&*name.local) => make!(HTMLElement), + _ => make!(HTMLUnknownElement), } } diff --git a/servo/components/script/dom/customelementregistry.rs b/servo/components/script/dom/customelementregistry.rs index 89296884080d..a625d4641299 100644 --- a/servo/components/script/dom/customelementregistry.rs +++ b/servo/components/script/dom/customelementregistry.rs @@ -9,25 +9,26 @@ use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::CustomElemen use dom::bindings::codegen::Bindings::CustomElementRegistryBinding::ElementDefinitionOptions; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::FunctionBinding::Function; +use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior}; -use dom::bindings::error::{Error, ErrorResult, Fallible}; +use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception, throw_dom_exception}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::document::Document; use dom::domexception::{DOMErrorName, DOMException}; -use dom::element::Element; +use dom::element::{CustomElementState, Element}; use dom::globalscope::GlobalScope; use dom::htmlelement::HTMLElement; -use dom::node::Node; +use dom::node::{document_from_node, Node, window_from_node}; use dom::promise::Promise; use dom::window::Window; use dom_struct::dom_struct; use html5ever::{LocalName, Namespace, Prefix}; use js::conversions::ToJSValConvertible; use js::jsapi::{Construct1, IsCallable, IsConstructor, HandleValueArray, HandleObject, MutableHandleValue}; -use js::jsapi::{Heap, JS_GetProperty, JSAutoCompartment, JSContext}; +use js::jsapi::{Heap, JS_GetProperty, JS_SameValue, JSAutoCompartment, JSContext}; use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue}; use microtask::Microtask; use script_thread::ScriptThread; @@ -79,13 +80,13 @@ impl CustomElementRegistry { /// https://html.spec.whatwg.org/multipage/#look-up-a-custom-element-definition pub fn lookup_definition(&self, - local_name: LocalName, - is: Option) + local_name: &LocalName, + is: Option<&LocalName>) -> Option> { self.definitions.borrow().values().find(|definition| { // Step 4-5 - definition.local_name == local_name && - (definition.name == local_name || Some(&definition.name) == is.as_ref()) + definition.local_name == *local_name && + (definition.name == *local_name || Some(&definition.name) == is) }).cloned() } @@ -281,17 +282,28 @@ impl CustomElementRegistryMethods for CustomElementRegistry { self.element_definition_is_running.set(false); // Step 11 - let definition = CustomElementDefinition::new(name.clone(), - local_name, - constructor_, - observed_attributes, - callbacks); + let definition = Rc::new(CustomElementDefinition::new(name.clone(), + local_name.clone(), + constructor_, + observed_attributes, + callbacks)); // Step 12 - self.definitions.borrow_mut().insert(name.clone(), Rc::new(definition)); + self.definitions.borrow_mut().insert(name.clone(), definition.clone()); - // TODO: Step 13, 14, 15 - // Handle custom element upgrades + // Step 13 + let document = self.window.Document(); + + // Steps 14-15 + for candidate in document.upcast::().traverse_preorder().filter_map(Root::downcast::) { + let is = candidate.get_is(); + if *candidate.local_name() == local_name && + *candidate.namespace() == ns!(html) && + (extends.is_none() || is.as_ref() == Some(&name)) + { + ScriptThread::enqueue_upgrade_reaction(&*candidate, definition.clone()); + } + } // Step 16, 16.3 if let Some(promise) = self.when_defined.borrow_mut().remove(&name) { @@ -366,6 +378,12 @@ pub struct LifecycleCallbacks { attribute_changed_callback: Option>, } +#[derive(HeapSizeOf, JSTraceable, Clone)] +pub enum ConstructionStackEntry { + Element(Root), + AlreadyConstructedMarker, +} + /// https://html.spec.whatwg.org/multipage/#custom-element-definition #[derive(HeapSizeOf, JSTraceable, Clone)] pub struct CustomElementDefinition { @@ -379,6 +397,8 @@ pub struct CustomElementDefinition { pub observed_attributes: Vec, pub callbacks: LifecycleCallbacks, + + pub construction_stack: DOMRefCell>, } impl CustomElementDefinition { @@ -394,6 +414,7 @@ impl CustomElementDefinition { constructor: constructor, observed_attributes: observed_attributes, callbacks: callbacks, + construction_stack: Default::default(), } } @@ -453,10 +474,113 @@ impl CustomElementDefinition { } } +/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element +#[allow(unsafe_code)] +pub fn upgrade_element(definition: Rc, element: &Element) { + // Steps 1-2 + let state = element.get_custom_element_state(); + if state == CustomElementState::Custom || state == CustomElementState::Failed { + return; + } + + // Step 3 + for attr in element.attrs().iter() { + let local_name = attr.local_name().clone(); + let value = DOMString::from(&**attr.value()); + let namespace = attr.namespace().clone(); + ScriptThread::enqueue_callback_reaction(element, + CallbackReaction::AttributeChanged(local_name, None, Some(value), namespace), Some(definition.clone())); + } + + // Step 4 + if element.is_connected() { + ScriptThread::enqueue_callback_reaction(element, CallbackReaction::Connected, Some(definition.clone())); + } + + // Step 5 + definition.construction_stack.borrow_mut().push(ConstructionStackEntry::Element(Root::from_ref(element))); + + // Step 7 + let result = run_upgrade_constructor(&definition.constructor, element); + + definition.construction_stack.borrow_mut().pop(); + + // Step 7 exception handling + if let Err(error) = result { + // Step 7.1 + element.set_custom_element_state(CustomElementState::Failed); + + // Step 7.2 + element.clear_reaction_queue(); + + // Step 7.3 + let global = GlobalScope::current().expect("No current global"); + let cx = global.get_cx(); + unsafe { + throw_dom_exception(cx, &global, error); + report_pending_exception(cx, true); + } + return; + } + + // Step 8 + element.set_custom_element_state(CustomElementState::Custom); + + // Step 9 + element.set_custom_element_definition(definition); +} + +/// https://html.spec.whatwg.org/multipage/#concept-upgrade-an-element +/// Steps 7.1-7.2 +#[allow(unsafe_code)] +fn run_upgrade_constructor(constructor: &Rc, element: &Element) -> ErrorResult { + let window = window_from_node(element); + let cx = window.get_cx(); + rooted!(in(cx) let constructor_val = ObjectValue(constructor.callback())); + rooted!(in(cx) let mut element_val = UndefinedValue()); + unsafe { element.to_jsval(cx, element_val.handle_mut()); } + rooted!(in(cx) let mut construct_result = ptr::null_mut()); + { + // Go into the constructor's compartment + let _ac = JSAutoCompartment::new(cx, constructor.callback()); + let args = HandleValueArray::new(); + // Step 7.1 + if unsafe { !Construct1(cx, constructor_val.handle(), &args, construct_result.handle_mut()) } { + return Err(Error::JSFailed); + } + // Step 7.2 + let mut same = false; + rooted!(in(cx) let construct_result_val = ObjectValue(construct_result.get())); + if unsafe { !JS_SameValue(cx, construct_result_val.handle(), element_val.handle(), &mut same) } { + return Err(Error::JSFailed); + } + if !same { + return Err(Error::InvalidState); + } + } + Ok(()) +} + +/// https://html.spec.whatwg.org/multipage/#concept-try-upgrade +pub fn try_upgrade_element(element: &Element) { + // Step 1 + let document = document_from_node(element); + let namespace = element.namespace(); + let local_name = element.local_name(); + let is = element.get_is(); + if let Some(definition) = document.lookup_custom_element_definition(namespace, local_name, is.as_ref()) { + // Step 2 + ScriptThread::enqueue_upgrade_reaction(element, definition); + } +} + #[derive(HeapSizeOf, JSTraceable)] #[must_root] pub enum CustomElementReaction { - // TODO: Support upgrade reactions + Upgrade( + #[ignore_heap_size_of = "Rc"] + Rc + ), Callback( #[ignore_heap_size_of = "Rc"] Rc, @@ -470,6 +594,7 @@ impl CustomElementReaction { pub fn invoke(&self, element: &Element) { // Step 2.1 match *self { + CustomElementReaction::Upgrade(ref definition) => upgrade_element(definition.clone(), element), CustomElementReaction::Callback(ref callback, ref arguments) => { let arguments = arguments.iter().map(|arg| arg.handle()).collect(); let _ = callback.Call_(&*element, arguments, ExceptionHandling::Report); @@ -561,9 +686,12 @@ impl CustomElementReactionStack { /// https://html.spec.whatwg.org/multipage/#enqueue-a-custom-element-callback-reaction #[allow(unsafe_code)] - pub fn enqueue_callback_reaction(&self, element: &Element, reaction: CallbackReaction) { + pub fn enqueue_callback_reaction(&self, + element: &Element, + reaction: CallbackReaction, + definition: Option>) { // Step 1 - let definition = match element.get_custom_element_definition() { + let definition = match definition.or_else(|| element.get_custom_element_definition()) { Some(definition) => definition, None => return, }; @@ -628,6 +756,14 @@ impl CustomElementReactionStack { // Step 6 self.enqueue_element(element); } + + /// https://html.spec.whatwg.org/multipage/#enqueue-a-custom-element-upgrade-reaction + pub fn enqueue_upgrade_reaction(&self, element: &Element, definition: Rc) { + // Step 1 + element.push_upgrade_reaction(definition); + // Step 2 + self.enqueue_element(element); + } } /// https://html.spec.whatwg.org/multipage/#element-queue @@ -663,7 +799,7 @@ impl ElementQueue { } /// https://html.spec.whatwg.org/multipage/#valid-custom-element-name -fn is_valid_custom_element_name(name: &str) -> bool { +pub fn is_valid_custom_element_name(name: &str) -> bool { // Custom elment names must match: // PotentialCustomElementName ::= [a-z] (PCENChar)* '-' (PCENChar)* diff --git a/servo/components/script/dom/document.rs b/servo/components/script/dom/document.rs index c63295a06744..4f594f96357b 100644 --- a/servo/components/script/dom/document.rs +++ b/servo/components/script/dom/document.rs @@ -95,7 +95,7 @@ use dom_struct::dom_struct; use encoding::EncodingRef; use encoding::all::UTF_8; use euclid::{Point2D, Vector2D}; -use html5ever::{LocalName, QualName}; +use html5ever::{LocalName, Namespace, QualName}; use hyper::header::{Header, SetCookie}; use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcSender}; @@ -2001,13 +2001,19 @@ impl Document { /// https://html.spec.whatwg.org/multipage/#look-up-a-custom-element-definition pub fn lookup_custom_element_definition(&self, - local_name: LocalName, - is: Option) + namespace: &Namespace, + local_name: &LocalName, + is: Option<&LocalName>) -> Option> { if !PREFS.get("dom.customelements.enabled").as_boolean().unwrap_or(false) { return None; } + // Step 1 + if *namespace != ns!(html) { + return None; + } + // Step 2 if !self.has_browsing_context { return None; diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index 328dd76e822f..6aeef3ce9861 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -101,6 +101,7 @@ use std::cell::{Cell, Ref}; use std::convert::TryFrom; use std::default::Default; use std::fmt; +use std::mem; use std::rc::Rc; use style::CaseSensitivityExt; use style::applicable_declarations::ApplicableDeclarationBlock; @@ -149,6 +150,8 @@ pub struct Element { /// https://dom.spec.whatwg.org/#concept-element-custom-element-definition #[ignore_heap_size_of = "Rc"] custom_element_definition: DOMRefCell>>, + /// https://dom.spec.whatwg.org/#concept-element-custom-element-state + custom_element_state: Cell, } impl fmt::Debug for Element { @@ -178,6 +181,15 @@ pub enum CustomElementCreationMode { Asynchronous, } +/// https://dom.spec.whatwg.org/#concept-element-custom-element-state +#[derive(Clone, Copy, PartialEq, Eq, HeapSizeOf, JSTraceable)] +pub enum CustomElementState { + Undefined, + Failed, + Uncustomized, + Custom, +} + impl ElementCreator { pub fn is_parser_created(&self) -> bool { match *self { @@ -254,6 +266,7 @@ impl Element { selector_flags: Cell::new(ElementSelectorFlags::empty()), custom_element_reaction_queue: Default::default(), custom_element_definition: Default::default(), + custom_element_state: Cell::new(CustomElementState::Uncustomized), } } @@ -288,6 +301,14 @@ impl Element { self.is.borrow().clone() } + pub fn set_custom_element_state(&self, state: CustomElementState) { + self.custom_element_state.set(state); + } + + pub fn get_custom_element_state(&self) -> CustomElementState { + self.custom_element_state.get() + } + pub fn set_custom_element_definition(&self, definition: Rc) { *self.custom_element_definition.borrow_mut() = Some(definition); } @@ -300,12 +321,25 @@ impl Element { self.custom_element_reaction_queue.borrow_mut().push(CustomElementReaction::Callback(function, args)); } + pub fn push_upgrade_reaction(&self, definition: Rc) { + self.custom_element_reaction_queue.borrow_mut().push(CustomElementReaction::Upgrade(definition)); + } + + pub fn clear_reaction_queue(&self) { + self.custom_element_reaction_queue.borrow_mut().clear(); + } + pub fn invoke_reactions(&self) { - let mut reaction_queue = self.custom_element_reaction_queue.borrow_mut(); - for reaction in reaction_queue.iter() { - reaction.invoke(self); + // TODO: This is not spec compliant, as this will allow some reactions to be processed + // after clear_reaction_queue has been called. + rooted_vec!(let mut reactions); + while !self.custom_element_reaction_queue.borrow().is_empty() { + mem::swap(&mut *reactions, &mut *self.custom_element_reaction_queue.borrow_mut()); + for reaction in reactions.iter() { + reaction.invoke(self); + } + reactions.clear(); } - reaction_queue.clear(); } // https://drafts.csswg.org/cssom-view/#css-layout-box @@ -1077,7 +1111,7 @@ impl Element { if self.get_custom_element_definition().is_some() { let reaction = CallbackReaction::AttributeChanged(name, None, Some(value), namespace); - ScriptThread::enqueue_callback_reaction(self, reaction); + ScriptThread::enqueue_callback_reaction(self, reaction, None); } assert!(attr.GetOwnerElement().r() == Some(self)); @@ -1220,7 +1254,7 @@ impl Element { MutationObserver::queue_a_mutation_record(&self.node, mutation); let reaction = CallbackReaction::AttributeChanged(name, Some(old_value), None, namespace); - ScriptThread::enqueue_callback_reaction(self, reaction); + ScriptThread::enqueue_callback_reaction(self, reaction, None); self.attrs.borrow_mut().remove(idx); attr.set_owner(None); diff --git a/servo/components/script/dom/node.rs b/servo/components/script/dom/node.rs index d6420b0a6f1e..7503618884b7 100644 --- a/servo/components/script/dom/node.rs +++ b/servo/components/script/dom/node.rs @@ -30,7 +30,7 @@ use dom::bindings::str::{DOMString, USVString}; use dom::bindings::xmlname::namespace_from_domstring; use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers}; use dom::cssstylesheet::CSSStyleSheet; -use dom::customelementregistry::CallbackReaction; +use dom::customelementregistry::{CallbackReaction, try_upgrade_element}; use dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument}; use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; @@ -317,7 +317,7 @@ impl Node { node.style_and_layout_data.get().map(|d| node.dispose(d)); // https://dom.spec.whatwg.org/#concept-node-remove step 14 if let Some(element) = node.as_custom_element() { - ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Disconnected); + ScriptThread::enqueue_callback_reaction(&*element, CallbackReaction::Disconnected, None); } } @@ -1425,7 +1425,7 @@ impl Node { for descendant in node.traverse_preorder().filter_map(|d| d.as_custom_element()) { // Step 3.2. ScriptThread::enqueue_callback_reaction(&*descendant, - CallbackReaction::Adopted(old_doc.clone(), Root::from_ref(document))); + CallbackReaction::Adopted(old_doc.clone(), Root::from_ref(document)), None); } for descendant in node.traverse_preorder() { // Step 3.3. @@ -1639,12 +1639,13 @@ impl Node { for descendant in kid.traverse_preorder().filter_map(Root::downcast::) { // Step 7.7.2. if descendant.is_connected() { - // Step 7.7.2.1. if descendant.get_custom_element_definition().is_some() { - ScriptThread::enqueue_callback_reaction(&*descendant, CallbackReaction::Connected); + // Step 7.7.2.1. + ScriptThread::enqueue_callback_reaction(&*descendant, CallbackReaction::Connected, None); + } else { + // Step 7.7.2.2. + try_upgrade_element(&*descendant); } - // TODO: Step 7.7.2.2. - // Try to upgrade descendant. } } } diff --git a/servo/components/script/script_thread.rs b/servo/components/script/script_thread.rs index e87938bfa1e0..4a4657e28a51 100644 --- a/servo/components/script/script_thread.rs +++ b/servo/components/script/script_thread.rs @@ -39,7 +39,7 @@ use dom::bindings::str::DOMString; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::WRAP_CALLBACKS; -use dom::customelementregistry::{CallbackReaction, CustomElementReactionStack}; +use dom::customelementregistry::{CallbackReaction, CustomElementDefinition, CustomElementReactionStack}; use dom::document::{Document, DocumentSource, FocusType, HasBrowsingContext, IsHTMLDocument, TouchEventResult}; use dom::element::Element; use dom::event::{Event, EventBubbles, EventCancelable}; @@ -774,11 +774,22 @@ impl ScriptThread { }) } - pub fn enqueue_callback_reaction(element:&Element, reaction: CallbackReaction) { + pub fn enqueue_callback_reaction(element: &Element, + reaction: CallbackReaction, + definition: Option>) { SCRIPT_THREAD_ROOT.with(|root| { if let Some(script_thread) = root.get() { let script_thread = unsafe { &*script_thread }; - script_thread.custom_element_reaction_stack.enqueue_callback_reaction(element, reaction); + script_thread.custom_element_reaction_stack.enqueue_callback_reaction(element, reaction, definition); + } + }) + } + + pub fn enqueue_upgrade_reaction(element: &Element, definition: Rc) { + SCRIPT_THREAD_ROOT.with(|root| { + if let Some(script_thread) = root.get() { + let script_thread = unsafe { &*script_thread }; + script_thread.custom_element_reaction_stack.enqueue_upgrade_reaction(element, definition); } }) } diff --git a/servo/tests/unit/script/size_of.rs b/servo/tests/unit/script/size_of.rs index d6c4a6ad7f82..903ffc5ddc31 100644 --- a/servo/tests/unit/script/size_of.rs +++ b/servo/tests/unit/script/size_of.rs @@ -31,9 +31,9 @@ macro_rules! sizeof_checker ( // Update the sizes here sizeof_checker!(size_event_target, EventTarget, 40); sizeof_checker!(size_node, Node, 184); -sizeof_checker!(size_element, Element, 424); -sizeof_checker!(size_htmlelement, HTMLElement, 440); -sizeof_checker!(size_div, HTMLDivElement, 440); -sizeof_checker!(size_span, HTMLSpanElement, 440); +sizeof_checker!(size_element, Element, 432); +sizeof_checker!(size_htmlelement, HTMLElement, 448); +sizeof_checker!(size_div, HTMLDivElement, 448); +sizeof_checker!(size_span, HTMLSpanElement, 448); sizeof_checker!(size_text, Text, 216); sizeof_checker!(size_characterdata, CharacterData, 216); From ef8460e2961a5442de81b9e47a7a6bef55d24c2f Mon Sep 17 00:00:00 2001 From: Daosheng Mu Date: Tue, 8 Aug 2017 18:23:43 +0800 Subject: [PATCH 103/166] Bug 1388274 - Adjust WebVR telemetry histogram's high bound for user time spent; r=francois,kip MozReview-Commit-ID: JcQZTgVmxr3 --HG-- extra : rebase_source : e00eab62c6d661a410d46d165843d7985054b145 --- dom/vr/VREventObserver.cpp | 5 ++--- gfx/vr/gfxVROculus.cpp | 5 ++--- gfx/vr/gfxVROpenVR.cpp | 5 ++--- toolkit/components/telemetry/Histograms.json | 20 ++++++++++---------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/dom/vr/VREventObserver.cpp b/dom/vr/VREventObserver.cpp index 2661666379a1..eff8be4683ea 100644 --- a/dom/vr/VREventObserver.cpp +++ b/dom/vr/VREventObserver.cpp @@ -50,9 +50,8 @@ VREventObserver::DisconnectFromOwner() // The WebVR content is closed, and we will collect the telemetry info // for the users who view it in 2D view only. Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 0); - Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_2D, - static_cast((TimeStamp::Now() - mSpendTimeIn2DView) - .ToMilliseconds())); + Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_2D, + mSpendTimeIn2DView); } mWindow = nullptr; diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index 2f506c5b36b1..a0134beede1e 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -244,9 +244,8 @@ VROculusSession::StopPresentation() mLastPresentationEnd = TimeStamp::Now(); mPresenting = false; Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 1); - Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_OCULUS, - static_cast((TimeStamp::Now() - mPresentationStart) - .ToMilliseconds())); + Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OCULUS, + mPresentationStart); Refresh(); } } diff --git a/gfx/vr/gfxVROpenVR.cpp b/gfx/vr/gfxVROpenVR.cpp index 800d1807465e..564a82d64aeb 100644 --- a/gfx/vr/gfxVROpenVR.cpp +++ b/gfx/vr/gfxVROpenVR.cpp @@ -282,9 +282,8 @@ VRDisplayOpenVR::StopPresentation() mIsPresenting = false; Telemetry::Accumulate(Telemetry::WEBVR_USERS_VIEW_IN, 2); - Telemetry::Accumulate(Telemetry::WEBVR_TIME_SPEND_FOR_VIEWING_IN_OPENVR, - static_cast((TimeStamp::Now() - mPresentationStart) - .ToMilliseconds())); + Telemetry::AccumulateTimeDelta(Telemetry::WEBVR_TIME_SPENT_VIEWING_IN_OPENVR, + mPresentationStart); } bool diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 6cc5130bd80b..38e4d3649b62 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -13648,40 +13648,40 @@ "kind": "enumerated", "n_values": 3, "releaseChannelCollection": "opt-out", - "description": "The amount of users who view VR content in: 2D=0, Oculus=1, OpenVR=2." + "description": "The amount of sessions who view VR content in: 2D=0, Oculus=1, OpenVR=2." }, - "WEBVR_TIME_SPEND_FOR_VIEWING_IN_2D": { + "WEBVR_TIME_SPENT_VIEWING_IN_2D": { "record_in_processes": ["main", "content"], "alert_emails": ["dmu@mozilla.com"], "bug_numbers": [1306156], "expires_in_version": "never", "kind": "exponential", - "high": 50000, + "high": 1200000, "n_buckets": 100, "releaseChannelCollection": "opt-out", - "description": "The amount of time spend(ms) for users who view VR content in 2D." + "description": "The amount of time spent(ms) of a session for viewing VR content in 2D." }, - "WEBVR_TIME_SPEND_FOR_VIEWING_IN_OCULUS": { + "WEBVR_TIME_SPENT_VIEWING_IN_OCULUS": { "record_in_processes": ["main", "gpu"], "alert_emails": ["dmu@mozilla.com"], "bug_numbers": [1306156], "expires_in_version": "never", "kind": "exponential", - "high": 50000, + "high": 1200000, "n_buckets": 100, "releaseChannelCollection": "opt-out", - "description": "The amount of time spend(ms) for users who view VR content in Oculus." + "description": "The amount of time spent(ms) of a session for viewing content in Oculus." }, - "WEBVR_TIME_SPEND_FOR_VIEWING_IN_OPENVR": { + "WEBVR_TIME_SPENT_VIEWING_IN_OPENVR": { "record_in_processes": ["main", "gpu"], "alert_emails": ["dmu@mozilla.com"], "bug_numbers": [1306156], "expires_in_version": "never", "kind": "exponential", - "high": 50000, + "high": 1200000, "n_buckets": 100, "releaseChannelCollection": "opt-out", - "description": "The amount of time spend(ms) for users who view VR content in OpenVR." + "description": "The amount of time spent(ms) of a session for viewing content in OpenVR." }, "URLCLASSIFIER_UI_EVENTS": { "record_in_processes": ["main", "content"], From f73b286d2afe62a20fd9e192656f3dee21c0028d Mon Sep 17 00:00:00 2001 From: Haik Aftandilian Date: Wed, 9 Aug 2017 16:09:55 -0700 Subject: [PATCH 104/166] Bug 1386832 - Part 1 - Move non-sandbox-specific routines out of SandboxSettings. r=jimm Moves IsDevelopmentBuild(), GetRepoDir(), and GetObjectDir() out of SandboxSettings because they also need to be used by ExtensionProtocolHandler to do security checks on developer builds as a result of how developer builds rely on symlinks to the repo dir from system extension directories. Remove the Linux-implementation of GetRepoDir() and GetObjectDir() because the Linux content sandbox implementation and the ExtensionProtocolHandler checks don't need them. MozReview-Commit-ID: KwBFUnh6Cml --HG-- extra : rebase_source : 3529a18ea802699ff968b798a7c560613469809b --- dom/ipc/ContentChild.cpp | 133 +++++++++++++++ dom/ipc/ContentChild.h | 17 ++ security/sandbox/common/SandboxSettings.cpp | 174 -------------------- security/sandbox/common/SandboxSettings.h | 11 -- 4 files changed, 150 insertions(+), 185 deletions(-) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index a121fd7354d8..3f0aeb65c876 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -73,6 +73,10 @@ #include "GMPServiceChild.h" #include "NullPrincipal.h" +#if !defined(XP_WIN) +#include "mozilla/Omnijar.h" +#endif + #ifdef MOZ_GECKO_PROFILER #include "ChildProfilerController.h" #endif @@ -172,6 +176,14 @@ #include "mozilla/audio/AudioNotificationReceiver.h" #endif +#if defined(XP_MACOSX) +#include +// Info.plist key associated with the developer repo path +#define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath" +// Info.plist key associated with the developer repo object directory +#define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath" +#endif /* XP_MACOSX */ + #ifdef MOZ_X11 #include "mozilla/X11Util.h" #endif @@ -3549,4 +3561,125 @@ ContentChild::GetSpecificMessageEventTarget(const Message& aMsg) } } // namespace dom + +#if !defined(XP_WIN) +bool IsDevelopmentBuild() +{ + nsCOMPtr path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE); + // If the path doesn't exist, we're a dev build. + return path == nullptr; +} +#endif /* !XP_WIN */ + +#if defined(XP_MACOSX) +/* + * Helper function to read a string value for a given key from the .app's + * Info.plist. + */ +static nsresult +GetStringValueFromBundlePlist(const nsAString& aKey, nsAutoCString& aValue) +{ + CFBundleRef mainBundle = CFBundleGetMainBundle(); + if (mainBundle == nullptr) { + return NS_ERROR_FAILURE; + } + + // Read this app's bundle Info.plist as a dictionary + CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(mainBundle); + if (bundleInfoDict == nullptr) { + return NS_ERROR_FAILURE; + } + + nsAutoCString keyAutoCString = NS_ConvertUTF16toUTF8(aKey); + CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, + keyAutoCString.get(), + kCFStringEncodingUTF8); + if (key == nullptr) { + return NS_ERROR_FAILURE; + } + + CFStringRef value = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, key); + CFRelease(key); + if (value == nullptr) { + return NS_ERROR_FAILURE; + } + + CFIndex valueLength = CFStringGetLength(value); + if (valueLength == 0) { + return NS_ERROR_FAILURE; + } + + const char* valueCString = CFStringGetCStringPtr(value, + kCFStringEncodingUTF8); + if (valueCString) { + aValue.Assign(valueCString); + return NS_OK; + } + + CFIndex maxLength = + CFStringGetMaximumSizeForEncoding(valueLength, kCFStringEncodingUTF8) + 1; + char* valueBuffer = static_cast(moz_xmalloc(maxLength)); + if (!valueBuffer) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (!CFStringGetCString(value, valueBuffer, maxLength, + kCFStringEncodingUTF8)) { + free(valueBuffer); + return NS_ERROR_FAILURE; + } + + aValue.Assign(valueBuffer); + free(valueBuffer); + return NS_OK; +} + +/* + * Helper function for reading a path string from the .app's Info.plist + * and returning a directory object for that path with symlinks resolved. + */ +static nsresult +GetDirFromBundlePlist(const nsAString& aKey, nsIFile **aDir) +{ + nsresult rv; + + nsAutoCString dirPath; + rv = GetStringValueFromBundlePlist(aKey, dirPath); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr dir; + rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirPath), + false, + getter_AddRefs(dir)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dir->Normalize(); + NS_ENSURE_SUCCESS(rv, rv); + + bool isDirectory = false; + rv = dir->IsDirectory(&isDirectory); + NS_ENSURE_SUCCESS(rv, rv); + if (!isDirectory) { + return NS_ERROR_FILE_NOT_DIRECTORY; + } + + dir.swap(*aDir); + return NS_OK; +} + +nsresult +GetRepoDir(nsIFile **aRepoDir) +{ + MOZ_ASSERT(IsDevelopmentBuild()); + return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_REPO_KEY), aRepoDir); +} + +nsresult +GetObjDir(nsIFile **aObjDir) +{ + MOZ_ASSERT(IsDevelopmentBuild()); + return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_OBJ_KEY), aObjDir); +} +#endif /* XP_MACOSX */ + } // namespace mozilla diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index e2cc07dfdab6..73d41c783804 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -40,6 +40,23 @@ class ChildProfilerController; using mozilla::loader::PScriptCacheChild; +#if !defined(XP_WIN) +// Returns whether or not the currently running build is an unpackaged +// developer build. This check is implemented by looking for omni.ja in the +// the obj/dist dir. We use this routine to detect when the build dir will +// use symlinks to the repo and object dir. On Windows, dev builds don't +// use symlinks. +bool IsDevelopmentBuild(); +#endif /* !XP_WIN */ + +#if defined(XP_MACOSX) +// Return the repo directory and the repo object directory respectively. These +// should only be used on Mac developer builds to determine the path to the +// repo or object directory. +nsresult GetRepoDir(nsIFile **aRepoDir); +nsresult GetObjDir(nsIFile **aObjDir); +#endif /* XP_MACOSX */ + namespace ipc { class OptionalURIParams; class URIParams; diff --git a/security/sandbox/common/SandboxSettings.cpp b/security/sandbox/common/SandboxSettings.cpp index 918ccc9b7bf6..1e07edceda41 100644 --- a/security/sandbox/common/SandboxSettings.cpp +++ b/security/sandbox/common/SandboxSettings.cpp @@ -6,185 +6,11 @@ #include "mozISandboxSettings.h" -#include "mozilla/Omnijar.h" #include "mozilla/ModuleUtils.h" #include "mozilla/Preferences.h" -#include "nsDirectoryServiceDefs.h" - -#if defined(XP_MACOSX) -#include -// Info.plist key associated with the developer repo path -#define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath" -// Info.plist key associated with the developer repo object directory -#define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath" -#else -#include "prenv.h" -#endif /* XP_MACOSX */ - namespace mozilla { -bool IsDevelopmentBuild() -{ - nsCOMPtr path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE); - // If the path doesn't exist, we're a dev build. - return path == nullptr; -} - -#if defined(XP_MACOSX) -/* - * Helper function to read a string value for a given key from the .app's - * Info.plist. - */ -static nsresult -GetStringValueFromBundlePlist(const nsAString& aKey, nsAutoCString& aValue) -{ - CFBundleRef mainBundle = CFBundleGetMainBundle(); - if (mainBundle == nullptr) { - return NS_ERROR_FAILURE; - } - - // Read this app's bundle Info.plist as a dictionary - CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(mainBundle); - if (bundleInfoDict == nullptr) { - return NS_ERROR_FAILURE; - } - - nsAutoCString keyAutoCString = NS_ConvertUTF16toUTF8(aKey); - CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, - keyAutoCString.get(), - kCFStringEncodingUTF8); - if (key == nullptr) { - return NS_ERROR_FAILURE; - } - - CFStringRef value = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, key); - CFRelease(key); - if (value == nullptr) { - return NS_ERROR_FAILURE; - } - - CFIndex valueLength = CFStringGetLength(value); - if (valueLength == 0) { - return NS_ERROR_FAILURE; - } - - const char* valueCString = CFStringGetCStringPtr(value, - kCFStringEncodingUTF8); - if (valueCString) { - aValue.Assign(valueCString); - return NS_OK; - } - - CFIndex maxLength = - CFStringGetMaximumSizeForEncoding(valueLength, kCFStringEncodingUTF8) + 1; - char* valueBuffer = static_cast(moz_xmalloc(maxLength)); - if (!valueBuffer) { - return NS_ERROR_OUT_OF_MEMORY; - } - - if (!CFStringGetCString(value, valueBuffer, maxLength, - kCFStringEncodingUTF8)) { - free(valueBuffer); - return NS_ERROR_FAILURE; - } - - aValue.Assign(valueBuffer); - free(valueBuffer); - return NS_OK; -} - -/* - * Helper function for reading a path string from the .app's Info.plist - * and returning a directory object for that path with symlinks resolved. - */ -static nsresult -GetDirFromBundlePlist(const nsAString& aKey, nsIFile **aDir) -{ - nsresult rv; - - nsAutoCString dirPath; - rv = GetStringValueFromBundlePlist(aKey, dirPath); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr dir; - rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirPath), - false, - getter_AddRefs(dir)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = dir->Normalize(); - NS_ENSURE_SUCCESS(rv, rv); - - bool isDirectory = false; - rv = dir->IsDirectory(&isDirectory); - NS_ENSURE_SUCCESS(rv, rv); - if (!isDirectory) { - return NS_ERROR_FILE_NOT_DIRECTORY; - } - - dir.swap(*aDir); - return NS_OK; -} - -#else /* !XP_MACOSX */ - -/* - * Helper function for getting a directory object for a given env variable - */ -static nsresult -GetDirFromEnv(const char* aEnvVar, nsIFile **aDir) -{ - nsresult rv; - - nsCOMPtr dir; - const char *dir_path = PR_GetEnv(aEnvVar); - if (!dir_path) { - return NS_ERROR_INVALID_ARG; - } - - rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dir_path), - false, - getter_AddRefs(dir)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = dir->Normalize(); - NS_ENSURE_SUCCESS(rv, rv); - - bool isDirectory = false; - rv = dir->IsDirectory(&isDirectory); - NS_ENSURE_SUCCESS(rv, rv); - if (!isDirectory) { - return NS_ERROR_FILE_NOT_DIRECTORY; - } - - dir.swap(*aDir); - return NS_OK; -} -#endif /* XP_MACOSX */ - -nsresult -GetRepoDir(nsIFile **aRepoDir) -{ - MOZ_ASSERT(IsDevelopmentBuild()); -#if defined(XP_MACOSX) - return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_REPO_KEY), aRepoDir); -#else - return GetDirFromEnv("MOZ_DEVELOPER_REPO_DIR", aRepoDir); -#endif /* XP_MACOSX */ -} - -nsresult -GetObjDir(nsIFile **aObjDir) -{ - MOZ_ASSERT(IsDevelopmentBuild()); -#if defined(XP_MACOSX) - return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_OBJ_KEY), aObjDir); -#else - return GetDirFromEnv("MOZ_DEVELOPER_OBJ_DIR", aObjDir); -#endif /* XP_MACOSX */ -} - int GetEffectiveContentSandboxLevel() { int level = Preferences::GetInt("security.sandbox.content.level"); // On Windows and macOS, enforce a minimum content sandbox level of 1 (except on diff --git a/security/sandbox/common/SandboxSettings.h b/security/sandbox/common/SandboxSettings.h index bbbf564fabe9..03d21e3ffacd 100644 --- a/security/sandbox/common/SandboxSettings.h +++ b/security/sandbox/common/SandboxSettings.h @@ -13,16 +13,5 @@ namespace mozilla { // minimum allowed level. int GetEffectiveContentSandboxLevel(); -// Returns whether or not the currently running build is a development build - -// where development build means "the files in the .app are symlinks to the src -// directory". This check is implemented by looking for omni.ja in -// .app/Contents/Resources/. -bool IsDevelopmentBuild(); - -// Return the repo directory and the repo object directory respectively. These -// should only be used on developer builds to determine the path to the repo -// or object directory. -nsresult GetRepoDir(nsIFile **aRepoDir); -nsresult GetObjDir(nsIFile **aObjDir); } #endif // mozilla_SandboxPolicies_h From f5314b4f602d3c4cef4b50d341dc865d45dfee9b Mon Sep 17 00:00:00 2001 From: Haik Aftandilian Date: Wed, 9 Aug 2017 16:11:59 -0700 Subject: [PATCH 105/166] Bug 1386832 - Part 2 - Make Linux dev build security check exception not depend on MOZ_DEVELOPER_REPO. r=jimm For Linux dev builds, change the developer build unpacked security check exception to not depend on knowing the repo dir because MOZ_DEVELOPER_REPO isn't reliably set whenever the firefox binary is run. Instead, make sure the extension root directory is within NS_GRE_DIR. Use both checks on Mac. MozReview-Commit-ID: IsbbNS58yf8 --HG-- extra : rebase_source : 64d1008a0513938edc111d12cb9fb28d2048ac82 --- .../protocol/res/ExtensionProtocolHandler.cpp | 131 ++++++++++++++---- .../protocol/res/ExtensionProtocolHandler.h | 54 +++++++- 2 files changed, 155 insertions(+), 30 deletions(-) diff --git a/netwerk/protocol/res/ExtensionProtocolHandler.cpp b/netwerk/protocol/res/ExtensionProtocolHandler.cpp index 776ccc70c559..8a05792e7108 100644 --- a/netwerk/protocol/res/ExtensionProtocolHandler.cpp +++ b/netwerk/protocol/res/ExtensionProtocolHandler.cpp @@ -7,6 +7,7 @@ #include "ExtensionProtocolHandler.h" #include "mozilla/ClearOnShutdown.h" +#include "mozilla/dom/ContentChild.h" #include "mozilla/ExtensionPolicyService.h" #include "mozilla/FileUtils.h" #include "mozilla/ipc/IPCStreamUtils.h" @@ -20,7 +21,7 @@ #include "LoadInfo.h" #include "nsContentUtils.h" #include "nsServiceManagerUtils.h" -#include "nsContentUtils.h" +#include "nsDirectoryServiceDefs.h" #include "nsIFile.h" #include "nsIFileChannel.h" #include "nsIFileStreams.h" @@ -45,10 +46,6 @@ #include "WinUtils.h" #endif -#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) -#include "mozilla/SandboxSettings.h" -#endif - #define EXTENSION_SCHEME "moz-extension" using mozilla::ipc::FileDescriptor; using OptionalIPCStream = mozilla::ipc::OptionalIPCStream; @@ -367,9 +364,12 @@ ExtensionProtocolHandler::GetSingleton() ExtensionProtocolHandler::ExtensionProtocolHandler() : SubstitutingProtocolHandler(EXTENSION_SCHEME) -#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) +#if !defined(XP_WIN) +#if defined(XP_MACOSX) , mAlreadyCheckedDevRepo(false) -#endif +#endif /* XP_MACOSX */ + , mAlreadyCheckedAppDir(false) +#endif /* ! XP_WIN */ { mUseRemoteFileChannels = IsNeckoChild() && Preferences::GetBool("extensions.webextensions.protocol.remote"); @@ -524,32 +524,118 @@ ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI, return NS_OK; } -#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) -// The |aRequestedFile| argument must already be Normalize()'d Result -ExtensionProtocolHandler::DevRepoContains(nsIFile* aRequestedFile, - bool *aResult) +ExtensionProtocolHandler::AllowExternalResource(nsIFile* aExtensionDir, + nsIFile* aRequestedFile, + bool* aResult) { MOZ_ASSERT(!IsNeckoChild()); MOZ_ASSERT(aResult); *aResult = false; - // On the first invocation, set mDevRepo if this is a development build +#if defined(XP_WIN) + // On Windows, dev builds don't use symlinks so we never need to + // allow a resource from outside of the extension dir. + return Ok(); +#else + if (!mozilla::IsDevelopmentBuild()) { + return Ok(); + } + + // On Mac and Linux unpackaged dev builds, system extensions use + // symlinks to point to resources in the repo dir which we have to + // allow loading. Before we allow an unpacked extension to load a + // resource outside of the extension dir, we make sure the extension + // dir is within the app directory. + MOZ_TRY(AppDirContains(aExtensionDir, aResult)); + if (!*aResult) { + return Ok(); + } + +#if defined(XP_MACOSX) + // Additionally, on Mac dev builds, we make sure that the requested + // resource is within the repo dir. We don't perform this check on Linux + // because we don't have a reliable path to the repo dir on Linux. + MOZ_TRY(DevRepoContains(aRequestedFile, aResult)); +#endif /* XP_MACOSX */ + + return Ok(); +#endif /* defined(XP_WIN) */ +} + +#if defined(XP_MACOSX) +// The |aRequestedFile| argument must already be Normalize()'d +Result +ExtensionProtocolHandler::DevRepoContains(nsIFile* aRequestedFile, + bool* aResult) +{ + MOZ_ASSERT(mozilla::IsDevelopmentBuild()); + MOZ_ASSERT(!IsNeckoChild()); + MOZ_ASSERT(aResult); + *aResult = false; + + // On the first invocation, set mDevRepo if (!mAlreadyCheckedDevRepo) { mAlreadyCheckedDevRepo = true; - if (mozilla::IsDevelopmentBuild()) { - NS_TRY(mozilla::GetRepoDir(getter_AddRefs(mDevRepo))); + NS_TRY(mozilla::GetRepoDir(getter_AddRefs(mDevRepo))); + if (MOZ_LOG_TEST(gExtProtocolLog, LogLevel::Debug)) { + nsAutoCString repoPath; + Unused << mDevRepo->GetNativePath(repoPath); + LOG("Repo path: %s", repoPath.get()); } } if (mDevRepo) { - // This is a development build NS_TRY(mDevRepo->Contains(aRequestedFile, aResult)); } return Ok(); } -#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */ +#endif /* XP_MACOSX */ + +#if !defined(XP_WIN) +Result +ExtensionProtocolHandler::AppDirContains(nsIFile* aExtensionDir, + bool* aResult) +{ + MOZ_ASSERT(mozilla::IsDevelopmentBuild()); + MOZ_ASSERT(!IsNeckoChild()); + MOZ_ASSERT(aResult); + *aResult = false; + + // On the first invocation, set mAppDir + if (!mAlreadyCheckedAppDir) { + mAlreadyCheckedAppDir = true; + NS_TRY(NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(mAppDir))); + if (MOZ_LOG_TEST(gExtProtocolLog, LogLevel::Debug)) { + nsAutoCString appDirPath; + Unused << mAppDir->GetNativePath(appDirPath); + LOG("AppDir path: %s", appDirPath.get()); + } + } + + if (mAppDir) { + NS_TRY(mAppDir->Contains(aExtensionDir, aResult)); + } + + return Ok(); +} +#endif /* !defined(XP_WIN) */ + +static void +LogExternalResourceError(nsIFile* aExtensionDir, nsIFile* aRequestedFile) +{ + MOZ_ASSERT(aExtensionDir); + MOZ_ASSERT(aRequestedFile); + + nsAutoCString extensionDirPath, requestedFilePath; + Unused << aExtensionDir->GetNativePath(extensionDirPath); + Unused << aRequestedFile->GetNativePath(requestedFilePath); + + LOG("Rejecting external unpacked extension resource [%s] from " + "extension directory [%s]", requestedFilePath.get(), + extensionDirPath.get()); +} Result, nsresult> ExtensionProtocolHandler::NewStream(nsIURI* aChildURI, bool* aTerminateSender) @@ -659,17 +745,12 @@ ExtensionProtocolHandler::NewStream(nsIURI* aChildURI, bool* aTerminateSender) bool isResourceFromExtensionDir = false; NS_TRY(extensionDir->Contains(requestedFile, &isResourceFromExtensionDir)); if (!isResourceFromExtensionDir) { -#if defined(XP_WIN) - return Err(NS_ERROR_FILE_ACCESS_DENIED); -#elif defined(MOZ_CONTENT_SANDBOX) - // On a dev build, we allow an unpacked resource that isn't - // from the extension directory as long as it is from the repo. - bool isResourceFromDevRepo = false; - MOZ_TRY(DevRepoContains(requestedFile, &isResourceFromDevRepo)); - if (!isResourceFromDevRepo) { + bool isAllowed = false; + MOZ_TRY(AllowExternalResource(extensionDir, requestedFile, &isAllowed)); + if (!isAllowed) { + LogExternalResourceError(extensionDir, requestedFile); return Err(NS_ERROR_FILE_ACCESS_DENIED); } -#endif /* defined(XP_WIN) */ } nsCOMPtr inputStream; diff --git a/netwerk/protocol/res/ExtensionProtocolHandler.h b/netwerk/protocol/res/ExtensionProtocolHandler.h index 01cb695ea14b..4797930ff668 100644 --- a/netwerk/protocol/res/ExtensionProtocolHandler.h +++ b/netwerk/protocol/res/ExtensionProtocolHandler.h @@ -144,21 +144,38 @@ private: nsACString& aResolvedSpec, nsIChannel** aRetVal); -#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) + /** + * Sets the aResult outparam to true if this unpacked extension load of + * a resource that is outside the extension dir should be allowed. This + * is only allowed for system extensions on Mac and Linux dev builds. + * + * @param aExtensionDir the extension directory. Argument must be an + * nsIFile for which Normalize() has already been called. + * @param aRequestedFile the requested web-accessible resource file. Argument + * must be an nsIFile for which Normalize() has already been called. + * @param aResult outparam set to true when the load of the requested file + * should be allowed. + */ + Result AllowExternalResource(nsIFile* aExtensionDir, + nsIFile* aRequestedFile, + bool* aResult); + +#if defined(XP_MACOSX) /** * Sets the aResult outparam to true if we are a developer build with the * repo dir environment variable set and the requested file resides in the * repo dir. Developer builds may load system extensions with web-accessible * resources that are symlinks to files in the repo dir. This method is for * checking if an unpacked resource requested by the child is from the repo. - * The requested file must be already Normalized(). + * The requested file must be already Normalized(). Only compile this for + * Mac because the repo dir isn't always available on Linux. * * @param aRequestedFile the requested web-accessible resource file. Argument * must be an nsIFile for which Normalize() has already been called. * @param aResult outparam set to true on development builds when the - * requested file resides in the repo + * requested file resides in the repo. */ - Result DevRepoContains(nsIFile* aRequestedFile, bool *aResult); + Result DevRepoContains(nsIFile* aRequestedFile, bool* aResult); // On development builds, this points to development repo. Lazily set. nsCOMPtr mDevRepo; @@ -166,7 +183,34 @@ private: // Set to true once we've already tried to load the dev repo path, // allowing for lazy initialization of |mDevRepo|. bool mAlreadyCheckedDevRepo; -#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */ +#endif /* XP_MACOSX */ + +#if !defined(XP_WIN) + /** + * Sets the aResult outparam to true if we are a developer build and the + * provided directory is within the NS_GRE_DIR directory. Developer builds + * may load system extensions with web-accessible resources that are symlinks + * to files outside of the extension dir to the repo dir. This method is for + * checking if an extension directory is within NS_GRE_DIR. In that case, we + * consider the extension a system extension and allow it to use symlinks to + * resources outside of the extension dir. This exception is only applied + * to loads for unpacked extensions in unpackaged developer builds. + * The requested dir must be already Normalized(). + * + * @param aExtensionDir the extension directory. Argument must be an + * nsIFile for which Normalize() has already been called. + * @param aResult outparam set to true on development builds when the + * requested file resides in the repo. + */ + Result AppDirContains(nsIFile* aExtensionDir, bool* aResult); + + // On development builds, cache the NS_GRE_DIR repo. Lazily set. + nsCOMPtr mAppDir; + + // Set to true once we've already read the AppDir, allowing for lazy + // initialization of |mAppDir|. + bool mAlreadyCheckedAppDir; +#endif /* !defined(XP_WIN) */ // Used for opening JAR files off the main thread when we just need to // obtain a file descriptor to send back to the child. From 59bb5e96e72b33f8e138c094d0143be386d69c85 Mon Sep 17 00:00:00 2001 From: Brad Werth Date: Wed, 9 Aug 2017 18:24:48 -0500 Subject: [PATCH 106/166] servo: Merge #18024 - Rework MediaType to be an atom-based struct instead of an enum (from bradwerth:mediatypeAtom); r=emilio MozReview-Commit-ID: 1Tfrs9PBkhA https://bugzilla.mozilla.org/show_bug.cgi?id=1371395 https://reviewboard.mozilla.org/r/163194/ --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: faf5b1f797c243c5036973a191d3abae36de4138 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 16506c8cce172296f698807039dc36bbd759227e --- servo/components/atoms/static_atoms.txt | 3 + servo/components/layout_thread/lib.rs | 4 +- servo/components/script/dom/mediaquerylist.rs | 2 +- servo/components/style/gecko/media_queries.rs | 20 ++++--- servo/components/style/media_queries.rs | 60 +++++++++---------- servo/components/style/str.rs | 11 ++++ servo/tests/unit/style/media_queries.rs | 46 +++++++------- servo/tests/unit/style/stylist.rs | 6 +- servo/tests/unit/style/viewport.rs | 12 ++-- 9 files changed, 92 insertions(+), 72 deletions(-) diff --git a/servo/components/atoms/static_atoms.txt b/servo/components/atoms/static_atoms.txt index 56d949eff5d9..9a878b09017b 100644 --- a/servo/components/atoms/static_atoms.txt +++ b/servo/components/atoms/static_atoms.txt @@ -70,3 +70,6 @@ gattserverdisconnected onchange reftest-wait + +screen +print diff --git a/servo/components/layout_thread/lib.rs b/servo/components/layout_thread/lib.rs index d94b4ef6094d..26d1ef7bb412 100644 --- a/servo/components/layout_thread/lib.rs +++ b/servo/components/layout_thread/lib.rs @@ -481,7 +481,7 @@ impl LayoutThread { // The device pixel ratio is incorrect (it does not have the hidpi value), // but it will be set correctly when the initial reflow takes place. let device = Device::new( - MediaType::Screen, + MediaType::screen(), opts::get().initial_window_size.to_f32() * ScaleFactor::new(1.0), ScaleFactor::new(opts::get().device_pixels_per_px.unwrap_or(1.0))); @@ -1156,7 +1156,7 @@ impl LayoutThread { let document_shared_lock = document.style_shared_lock(); self.document_shared_lock = Some(document_shared_lock.clone()); let author_guard = document_shared_lock.read(); - let device = Device::new(MediaType::Screen, initial_viewport, device_pixel_ratio); + let device = Device::new(MediaType::screen(), initial_viewport, device_pixel_ratio); self.stylist.set_device(device, &author_guard, &data.document_stylesheets); self.viewport_size = diff --git a/servo/components/script/dom/mediaquerylist.rs b/servo/components/script/dom/mediaquerylist.rs index 1765ef88bce5..60cb875163e6 100644 --- a/servo/components/script/dom/mediaquerylist.rs +++ b/servo/components/script/dom/mediaquerylist.rs @@ -77,7 +77,7 @@ impl MediaQueryList { if let Some(window_size) = self.document.window().window_size() { let viewport_size = window_size.initial_viewport; let device_pixel_ratio = window_size.device_pixel_ratio; - let device = Device::new(MediaType::Screen, viewport_size, device_pixel_ratio); + let device = Device::new(MediaType::screen(), viewport_size, device_pixel_ratio); self.media_query_list.evaluate(&device, self.document.quirks_mode()) } else { false diff --git a/servo/components/style/gecko/media_queries.rs b/servo/components/style/gecko/media_queries.rs index a7ba27d8414b..3bd1a85f442a 100644 --- a/servo/components/style/gecko/media_queries.rs +++ b/servo/components/style/gecko/media_queries.rs @@ -18,6 +18,7 @@ use gecko_bindings::structs::{nsCSSKeyword, nsCSSProps_KTableEntry, nsCSSValue, use gecko_bindings::structs::{nsMediaExpression_Range, nsMediaFeature}; use gecko_bindings::structs::{nsMediaFeature_ValueType, nsMediaFeature_RangeType, nsMediaFeature_RequirementFlags}; use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned}; +use gecko_bindings::structs::nsIAtom; use media_queries::MediaType; use parser::ParserContext; use properties::{ComputedValues, StyleBuilder}; @@ -31,7 +32,7 @@ use string_cache::Atom; use style_traits::{CSSPixel, DevicePixel}; use style_traits::{ToCss, ParseError, StyleParseError}; use style_traits::viewport::ViewportConstraints; -use values::{CSSFloat, specified}; +use values::{CSSFloat, specified, CustomIdent}; use values::computed::{self, ToComputedValue}; /// The `Device` in Gecko wraps a pres context, has a default values computed, @@ -140,15 +141,16 @@ impl Device { /// Returns the current media type of the device. pub fn media_type(&self) -> MediaType { unsafe { - // FIXME(emilio): Gecko allows emulating random media with - // mIsEmulatingMedia / mMediaEmulated . Refactor both sides so that - // is supported (probably just making MediaType an Atom). - if self.pres_context().mMedium == atom!("screen").as_ptr() { - MediaType::Screen + // Gecko allows emulating random media with mIsEmulatingMedia and + // mMediaEmulated. + let context = self.pres_context(); + let medium_to_use = if context.mIsEmulatingMedia() != 0 { + context.mMediaEmulated.raw::() } else { - debug_assert!(self.pres_context().mMedium == atom!("print").as_ptr()); - MediaType::Print - } + context.mMedium + }; + + MediaType(CustomIdent(Atom::from(medium_to_use))) } } diff --git a/servo/components/style/media_queries.rs b/servo/components/style/media_queries.rs index b6bde057b3c1..9d3f113f0a98 100644 --- a/servo/components/style/media_queries.rs +++ b/servo/components/style/media_queries.rs @@ -13,7 +13,9 @@ use parser::ParserContext; use selectors::parser::SelectorParseError; use serialize_comma_separated_list; use std::fmt; +use str::string_as_ascii_lowercase; use style_traits::{ToCss, ParseError, StyleParseError}; +use values::CustomIdent; #[cfg(feature = "servo")] pub use servo::media_queries::{Device, Expression}; @@ -108,9 +110,7 @@ impl ToCss for MediaQuery { write!(dest, "all")?; } }, - MediaQueryType::Known(MediaType::Screen) => write!(dest, "screen")?, - MediaQueryType::Known(MediaType::Print) => write!(dest, "print")?, - MediaQueryType::Unknown(ref desc) => write!(dest, "{}", desc)?, + MediaQueryType::Concrete(MediaType(ref desc)) => desc.to_css(dest)?, } if self.expressions.is_empty() { @@ -137,35 +137,25 @@ impl ToCss for MediaQuery { pub enum MediaQueryType { /// A media type that matches every device. All, - /// A known media type, that we parse and understand. - Known(MediaType), - /// An unknown media type. - Unknown(Atom), + /// A specific media type. + Concrete(MediaType), } impl MediaQueryType { fn parse(ident: &str) -> Result { match_ignore_ascii_case! { ident, "all" => return Ok(MediaQueryType::All), - // From https://drafts.csswg.org/mediaqueries/#mq-syntax: - // - // The production does not include the keywords only, - // not, and, and or. - "not" | "or" | "and" | "only" => return Err(()), _ => (), }; - Ok(match MediaType::parse(ident) { - Some(media_type) => MediaQueryType::Known(media_type), - None => MediaQueryType::Unknown(Atom::from(ident)), - }) + // If parseable, accept this type as a concrete type. + MediaType::parse(ident).map(MediaQueryType::Concrete) } fn matches(&self, other: MediaType) -> bool { match *self { MediaQueryType::All => true, - MediaQueryType::Known(ref known_type) => *known_type == other, - MediaQueryType::Unknown(..) => false, + MediaQueryType::Concrete(ref known_type) => *known_type == other, } } } @@ -173,20 +163,30 @@ impl MediaQueryType { /// https://drafts.csswg.org/mediaqueries/#media-types #[derive(PartialEq, Eq, Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum MediaType { - /// The "screen" media type. - Screen, - /// The "print" media type. - Print, -} +pub struct MediaType(pub CustomIdent); impl MediaType { - fn parse(name: &str) -> Option { - Some(match_ignore_ascii_case! { name, - "screen" => MediaType::Screen, - "print" => MediaType::Print, - _ => return None - }) + /// The `screen` media type. + pub fn screen() -> Self { + MediaType(CustomIdent(atom!("screen"))) + } + + /// The `print` media type. + pub fn print() -> Self { + MediaType(CustomIdent(atom!("print"))) + } + + fn parse(name: &str) -> Result { + // From https://drafts.csswg.org/mediaqueries/#mq-syntax: + // + // The production does not include the keywords not, or, and, and only. + // + // Here we also perform the to-ascii-lowercase part of the serialization + // algorithm: https://drafts.csswg.org/cssom/#serializing-media-queries + match_ignore_ascii_case! { name, + "not" | "or" | "and" | "only" => Err(()), + _ => Ok(MediaType(CustomIdent(Atom::from(string_as_ascii_lowercase(name))))), + } } } impl MediaQuery { diff --git a/servo/components/style/str.rs b/servo/components/style/str.rs index 92febb408249..a76bf98caf5b 100644 --- a/servo/components/style/str.rs +++ b/servo/components/style/str.rs @@ -8,6 +8,7 @@ use num_traits::ToPrimitive; use std::ascii::AsciiExt; +use std::borrow::Cow; use std::convert::AsRef; use std::iter::{Filter, Peekable}; use std::str::Split; @@ -151,3 +152,13 @@ pub fn starts_with_ignore_ascii_case(string: &str, prefix: &str) -> bool { string.len() >= prefix.len() && string.as_bytes()[0..prefix.len()].eq_ignore_ascii_case(prefix.as_bytes()) } + +/// Returns an ascii lowercase version of a string, only allocating if needed. +pub fn string_as_ascii_lowercase<'a>(input: &'a str) -> Cow<'a, str> { + if input.bytes().any(|c| matches!(c, b'A'...b'Z')) { + input.to_ascii_lowercase().into() + } else { + // Already ascii lowercase. + Cow::Borrowed(input) + } +} diff --git a/servo/tests/unit/style/media_queries.rs b/servo/tests/unit/style/media_queries.rs index 24dd06ef19b7..c7f39b226cb1 100644 --- a/servo/tests/unit/style/media_queries.rs +++ b/servo/tests/unit/style/media_queries.rs @@ -15,7 +15,7 @@ use style::media_queries::*; use style::servo::media_queries::*; use style::shared_lock::SharedRwLock; use style::stylesheets::{AllRules, Stylesheet, StylesheetInDocument, Origin, CssRule}; -use style::values::specified; +use style::values::{CustomIdent, specified}; use style_traits::ToCss; pub struct CSSErrorReporterTest; @@ -38,7 +38,7 @@ fn test_media_rule(css: &str, callback: F) let stylesheet = Stylesheet::from_str( css, url, Origin::Author, media_list, lock, None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64); - let dummy = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); + let dummy = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); let mut rule_count = 0; let guard = stylesheet.shared_lock.read(); for rule in stylesheet.iter_rules::(&dummy, &guard) { @@ -75,7 +75,7 @@ fn test_mq_screen() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -83,7 +83,7 @@ fn test_mq_screen() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -91,7 +91,7 @@ fn test_mq_screen() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); } @@ -102,7 +102,7 @@ fn test_mq_print() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -110,7 +110,7 @@ fn test_mq_print() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -118,7 +118,7 @@ fn test_mq_print() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); } @@ -129,7 +129,8 @@ fn test_mq_unknown() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete( + MediaType(CustomIdent(Atom::from("fridge")))), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -137,7 +138,8 @@ fn test_mq_unknown() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Only), css.to_owned()); - assert!(q.media_type == MediaQueryType::Unknown(Atom::from("glass")), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete( + MediaType(CustomIdent(Atom::from("glass")))), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); @@ -145,7 +147,8 @@ fn test_mq_unknown() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::Unknown(Atom::from("wood")), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete( + MediaType(CustomIdent(Atom::from("wood")))), css.to_owned()); assert!(q.expressions.len() == 0, css.to_owned()); }); } @@ -183,12 +186,12 @@ fn test_mq_or() { assert!(list.media_queries.len() == 2, css.to_owned()); let q0 = &list.media_queries[0]; assert!(q0.qualifier == None, css.to_owned()); - assert!(q0.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q0.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q0.expressions.len() == 0, css.to_owned()); let q1 = &list.media_queries[1]; assert!(q1.qualifier == None, css.to_owned()); - assert!(q1.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q1.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q1.expressions.len() == 0, css.to_owned()); }); } @@ -226,7 +229,7 @@ fn test_mq_expressions() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), @@ -238,7 +241,7 @@ fn test_mq_expressions() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(43.)), @@ -250,7 +253,7 @@ fn test_mq_expressions() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Print), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::print()), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { ExpressionKind::Width(Range::Eq(ref w)) => assert!(*w == specified::Length::from_px(43.)), @@ -262,7 +265,8 @@ fn test_mq_expressions() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == None, css.to_owned()); - assert!(q.media_type == MediaQueryType::Unknown(Atom::from("fridge")), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete( + MediaType(CustomIdent(Atom::from("fridge")))), css.to_owned()); assert!(q.expressions.len() == 1, css.to_owned()); match *q.expressions[0].kind_for_testing() { ExpressionKind::Width(Range::Max(ref w)) => assert!(*w == specified::Length::from_px(52.)), @@ -303,7 +307,7 @@ fn test_mq_multiple_expressions() { assert!(list.media_queries.len() == 1, css.to_owned()); let q = &list.media_queries[0]; assert!(q.qualifier == Some(Qualifier::Not), css.to_owned()); - assert!(q.media_type == MediaQueryType::Known(MediaType::Screen), css.to_owned()); + assert!(q.media_type == MediaQueryType::Concrete(MediaType::screen()), css.to_owned()); assert!(q.expressions.len() == 2, css.to_owned()); match *q.expressions[0].kind_for_testing() { ExpressionKind::Width(Range::Min(ref w)) => assert!(*w == specified::Length::from_px(100.)), @@ -341,7 +345,7 @@ fn test_mq_malformed_expressions() { #[test] fn test_matching_simple() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); media_query_test(&device, "@media not all { a { color: red; } }", 0); media_query_test(&device, "@media not screen { a { color: red; } }", 0); @@ -357,7 +361,7 @@ fn test_matching_simple() { #[test] fn test_matching_width() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); media_query_test(&device, "@media { a { color: red; } }", 1); @@ -398,7 +402,7 @@ fn test_matching_width() { #[test] fn test_matching_invalid() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), ScaleFactor::new(1.0)); media_query_test(&device, "@media fridge { a { color: red; } }", 0); media_query_test(&device, "@media screen and (height: 100px) { a { color: red; } }", 0); diff --git a/servo/tests/unit/style/stylist.rs b/servo/tests/unit/style/stylist.rs index 31f842b2d8d3..2e98964c1c11 100644 --- a/servo/tests/unit/style/stylist.rs +++ b/servo/tests/unit/style/stylist.rs @@ -222,7 +222,7 @@ fn test_insert() { } fn mock_stylist() -> Stylist { - let device = Device::new(MediaType::Screen, TypedSize2D::new(0f32, 0f32), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(0f32, 0f32), ScaleFactor::new(1.0)); Stylist::new(device, QuirksMode::NoQuirks) } @@ -230,9 +230,9 @@ fn mock_stylist() -> Stylist { fn test_stylist_device_accessors() { thread_state::initialize(thread_state::LAYOUT); let stylist = mock_stylist(); - assert_eq!(stylist.device().media_type(), MediaType::Screen); + assert_eq!(stylist.device().media_type(), MediaType::screen()); let mut stylist_mut = mock_stylist(); - assert_eq!(stylist_mut.device_mut().media_type(), MediaType::Screen); + assert_eq!(stylist_mut.device_mut().media_type(), MediaType::screen()); } #[test] diff --git a/servo/tests/unit/style/viewport.rs b/servo/tests/unit/style/viewport.rs index 3affe7434c48..35e0ad13e5ef 100644 --- a/servo/tests/unit/style/viewport.rs +++ b/servo/tests/unit/style/viewport.rs @@ -97,7 +97,7 @@ macro_rules! viewport_length { #[test] fn empty_viewport_rule() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); test_viewport_rule("@viewport {}", &device, |declarations, css| { println!("{}", css); @@ -120,7 +120,7 @@ macro_rules! assert_decl_eq { #[test] fn simple_viewport_rules() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); test_viewport_rule("@viewport { width: auto; height: auto;\ zoom: auto; min-zoom: 0; max-zoom: 200%;\ @@ -192,7 +192,7 @@ fn simple_meta_viewport_contents() { #[test] fn cascading_within_viewport_rule() { - let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); // normal order of appearance test_viewport_rule("@viewport { min-width: 200px; min-width: auto; }", @@ -258,7 +258,7 @@ fn cascading_within_viewport_rule() { #[test] fn multiple_stylesheets_cascading() { PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true)); - let device = Device::new(MediaType::Screen, TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), TypedSize2D::new(800., 600.), ScaleFactor::new(1.0)); let error_reporter = CSSErrorReporterTest; let shared_lock = SharedRwLock::new(); let stylesheets = vec![ @@ -314,7 +314,7 @@ fn constrain_viewport() { } let initial_viewport = TypedSize2D::new(800., 600.); - let device = Device::new(MediaType::Screen, initial_viewport, ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), initial_viewport, ScaleFactor::new(1.0)); let mut input = ParserInput::new(""); assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), None); @@ -363,7 +363,7 @@ fn constrain_viewport() { })); let initial_viewport = TypedSize2D::new(200., 150.); - let device = Device::new(MediaType::Screen, initial_viewport, ScaleFactor::new(1.0)); + let device = Device::new(MediaType::screen(), initial_viewport, ScaleFactor::new(1.0)); let mut input = ParserInput::new("width: 320px auto"); assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(input), QuirksMode::NoQuirks), Some(ViewportConstraints { From 64905fbd5a7d77518b0713dbe9af736f0671e9bf Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 9 Aug 2017 21:12:28 -0400 Subject: [PATCH 107/166] Backed out changesets 19b8d672b55d and 2980183d98fb (bug 1362338) for hazard analysis failures. --- parser/html/nsHtml5Atom.cpp | 16 +++++++++- parser/html/nsHtml5Atom.h | 2 +- xpcom/ds/nsAtomTable.cpp | 58 ++++++++++++------------------------- xpcom/ds/nsIAtom.idl | 3 -- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/parser/html/nsHtml5Atom.cpp b/parser/html/nsHtml5Atom.cpp index 343a69b3d232..120cfb85def5 100644 --- a/parser/html/nsHtml5Atom.cpp +++ b/parser/html/nsHtml5Atom.cpp @@ -40,6 +40,20 @@ nsHtml5Atom::~nsHtml5Atom() nsStringBuffer::FromData(mString)->Release(); } +NS_IMETHODIMP_(MozExternalRefCountType) +nsHtml5Atom::AddRef() +{ + NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom."); + return 2; +} + +NS_IMETHODIMP_(MozExternalRefCountType) +nsHtml5Atom::Release() +{ + NS_NOTREACHED("Attempt to Release an nsHtml5Atom."); + return 1; +} + NS_IMETHODIMP nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr) { @@ -47,7 +61,7 @@ nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_ERROR_UNEXPECTED; } -NS_IMETHODIMP +NS_IMETHODIMP nsHtml5Atom::ScriptableToString(nsAString& aBuf) { NS_NOTREACHED("Should not call ScriptableToString."); diff --git a/parser/html/nsHtml5Atom.h b/parser/html/nsHtml5Atom.h index be56b5ed6bab..c11fb0bade58 100644 --- a/parser/html/nsHtml5Atom.h +++ b/parser/html/nsHtml5Atom.h @@ -18,7 +18,7 @@ class nsHtml5Atom final : public nsIAtom { public: - NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; + NS_DECL_ISUPPORTS NS_DECL_NSIATOM explicit nsHtml5Atom(const nsAString& aString); diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 2f3bde28990b..634855f80170 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -128,16 +128,8 @@ private: ~DynamicAtom(); public: + NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIATOM - NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; - typedef mozilla::TrueType HasThreadSafeRefCnt; - - MozExternalRefCountType DoAddRef(); - MozExternalRefCountType DoRelease(); - -protected: - ThreadSafeAutoRefCnt mRefCnt; - NS_DECL_OWNINGTHREAD }; #if defined(NS_BUILD_REFCNT_LOGGING) @@ -207,11 +199,23 @@ public: // StaticAtom* pointer (in AtomTableClearEntry()), not an nsIAtom* pointer. ~StaticAtom() {} - NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final; + NS_DECL_ISUPPORTS NS_DECL_NSIATOM }; -NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom); +NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom) + +NS_IMETHODIMP_(MozExternalRefCountType) +StaticAtom::AddRef() +{ + return 2; +} + +NS_IMETHODIMP_(MozExternalRefCountType) +StaticAtom::Release() +{ + return 1; +} NS_IMETHODIMP DynamicAtom::ScriptableToString(nsAString& aBuf) @@ -275,30 +279,6 @@ StaticAtom::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) //---------------------------------------------------------------------- -NS_IMETHODIMP_(MozExternalRefCountType) -nsIAtom::AddRef() -{ - MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an nsHtml5Atom"); - if (!IsDynamicAtom()) { - MOZ_ASSERT(IsStaticAtom()); - return 2; - } - return static_cast(this)->DoAddRef(); -} - -NS_IMETHODIMP_(MozExternalRefCountType) -nsIAtom::Release() -{ - MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an nsHtml5Atom"); - if (!IsDynamicAtom()) { - MOZ_ASSERT(IsStaticAtom()); - return 1; - } - return static_cast(this)->DoRelease(); -} - -//---------------------------------------------------------------------- - /** * The shared hash table for atom lookups. * @@ -504,8 +484,8 @@ DynamicAtom::GCAtomTableLocked(const MutexAutoLock& aProofOfLock, NS_IMPL_QUERY_INTERFACE(DynamicAtom, nsIAtom) -MozExternalRefCountType -DynamicAtom::DoAddRef() +NS_IMETHODIMP_(MozExternalRefCountType) +DynamicAtom::AddRef(void) { nsrefcnt count = ++mRefCnt; if (count == 1) { @@ -522,8 +502,8 @@ static const uint32_t kAtomGCThreshold = 20; static const uint32_t kAtomGCThreshold = 10000; #endif -MozExternalRefCountType -DynamicAtom::DoRelease() +NS_IMETHODIMP_(MozExternalRefCountType) +DynamicAtom::Release(void) { MOZ_ASSERT(mRefCnt > 0); nsrefcnt count = --mRefCnt; diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index a050e7ee9113..60cddbee051e 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -95,9 +95,6 @@ interface nsIAtom : nsISupports return nsStringBuffer::FromData(mString); } - NS_IMETHOD_(MozExternalRefCountType) AddRef() final; - NS_IMETHOD_(MozExternalRefCountType) Release() final; - /** * A hashcode that is better distributed than the actual atom * pointer, for use in situations that need a well-distributed From 51838f82e6ea8b506ca93306143ae18a4fa77346 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:23:48 -0400 Subject: [PATCH 108/166] Bug 1387862 - Add initial support for ./mach lint -l yaml r=ahal,dustin We should have CI Lint YAML files in the tree. MozReview-Commit-ID: HYVWXzNnnzG --HG-- rename : tools/lint/flake8_/__init__.py => tools/lint/yamllint_/__init__.py extra : rebase_source : 635ef617eeba1cd1299366beb0c83232d42f0258 --- tools/lint/yaml.yml | 5 + tools/lint/yamllint_/__init__.py | 154 ++++++++++++++++++ .../lint/yamllint_/yamllint_requirements.txt | 21 +++ 3 files changed, 180 insertions(+) create mode 100644 tools/lint/yaml.yml create mode 100644 tools/lint/yamllint_/__init__.py create mode 100644 tools/lint/yamllint_/yamllint_requirements.txt diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml new file mode 100644 index 000000000000..9bea664e58e4 --- /dev/null +++ b/tools/lint/yaml.yml @@ -0,0 +1,5 @@ +yamllint: + description: YAML linter + extensions: ['yml', 'yaml'] + type: external + payload: yamllint_:lint diff --git a/tools/lint/yamllint_/__init__.py b/tools/lint/yamllint_/__init__.py new file mode 100644 index 000000000000..16fe34a61320 --- /dev/null +++ b/tools/lint/yamllint_/__init__.py @@ -0,0 +1,154 @@ +# 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/. + +import re +import os +import signal +import subprocess + +import which +from mozprocess import ProcessHandlerMixin + +from mozlint import result + + +here = os.path.abspath(os.path.dirname(__file__)) +YAMLLINT_REQUIREMENTS_PATH = os.path.join(here, 'yamllint_requirements.txt') + + +YAMLLINT_INSTALL_ERROR = """ +Unable to install correct version of yamllint +Try to install it manually with: + $ pip install -U --require-hashes -r {} +""".strip().format(YAMLLINT_REQUIREMENTS_PATH) + +YAMLLINT_FORMAT_REGEX = re.compile(r'(.*):(.*):(.*): \[(error|warning)\] (.*) \((.*)\)$') + +results = [] + + +class YAMLLintProcess(ProcessHandlerMixin): + def __init__(self, config, *args, **kwargs): + self.config = config + kwargs['processOutputLine'] = [self.process_line] + ProcessHandlerMixin.__init__(self, *args, **kwargs) + + def process_line(self, line): + try: + match = YAMLLINT_FORMAT_REGEX.match(line) + abspath, line, col, level, message, code = match.groups() + except AttributeError: + print('Unable to match yaml regex against output: {}'.format(line)) + return + + res = {'path': os.path.relpath(abspath, self.config['root']), + 'message': message, + 'level': level, + 'lineno': line, + 'column': col, + 'rule': code, + } + + results.append(result.from_config(self.config, **res)) + + def run(self, *args, **kwargs): + # protect against poor SIGINT handling. Handle it here instead + # so we can kill the process without a cryptic traceback. + orig = signal.signal(signal.SIGINT, signal.SIG_IGN) + ProcessHandlerMixin.run(self, *args, **kwargs) + signal.signal(signal.SIGINT, orig) + + +def get_yamllint_binary(): + """ + Returns the path of the first yamllint binary available + if not found returns None + """ + binary = os.environ.get('YAMLLINT') + if binary: + return binary + + try: + return which.which('yamllint') + except which.WhichError: + return None + + +def _run_pip(*args): + """ + Helper function that runs pip with subprocess + """ + try: + subprocess.check_output(['pip'] + list(args), + stderr=subprocess.STDOUT) + return True + except subprocess.CalledProcessError as e: + print(e.output) + return False + + +def reinstall_yamllint(): + """ + Try to install yamllint at the target version, returns True on success + otherwise prints the otuput of the pip command and returns False + """ + if _run_pip('install', '-U', + '--require-hashes', '-r', + YAMLLINT_REQUIREMENTS_PATH): + return True + + return False + + +def run_process(config, cmd): + proc = YAMLLintProcess(config, cmd) + proc.run() + try: + proc.wait() + except KeyboardInterrupt: + proc.kill() + + +def gen_yamllint_args(cmdargs, paths=None, conf_file=None): + args = cmdargs[:] + if isinstance(paths, basestring): + paths = [paths] + if conf_file: + return args + ['-c', conf_file] + paths + return args + paths + + +def lint(files, config, **lintargs): + + if not reinstall_yamllint(): + print(YAMLLINT_INSTALL_ERROR) + return 1 + + binary = get_yamllint_binary() + + cmdargs = [ + binary, + '-f', 'parsable' + ] + + config = config.copy() + config['root'] = lintargs['root'] + + # Run any paths with a .yamllint file in the directory separately so + # it gets picked up. This means only .yamllint files that live in + # directories that are explicitly included will be considered. + no_config = [] + for f in files: + yamllint_config = os.path.join(f, '.yamllint') + if not os.path.isfile(yamllint_config): + no_config.append(f) + continue + run_process(config, + gen_yamllint_args(cmdargs, conf_file=yamllint_config, paths=f)) + + if no_config: + run_process(config, + gen_yamllint_args(cmdargs, paths=no_config)) + + return results diff --git a/tools/lint/yamllint_/yamllint_requirements.txt b/tools/lint/yamllint_/yamllint_requirements.txt new file mode 100644 index 000000000000..b442a8f2ea70 --- /dev/null +++ b/tools/lint/yamllint_/yamllint_requirements.txt @@ -0,0 +1,21 @@ +yamllint==1.8.1 \ + --hash=sha256:806b21828ca92fd6e9f20d8eccfa53035e38041854bb4d1b666f271a7788dbcf \ + --hash=sha256:048743567ca9511e19222233ebb53795586a2cede07b79e801577e0a9b4f173c +PyYAML==3.12 \ + --hash=sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f \ + --hash=sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736 \ + --hash=sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269 \ + --hash=sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8 \ + --hash=sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4 \ + --hash=sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1 \ + --hash=sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab \ + --hash=sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab \ + --hash=sha256:5f84523c076ad14ff5e6c037fe1c89a7f73a3e04cf0377cb4d017014976433f3 \ + --hash=sha256:0c507b7f74b3d2dd4d1322ec8a94794927305ab4cebbe89cc47fe5e81541e6e8 \ + --hash=sha256:b4c423ab23291d3945ac61346feeb9a0dc4184999ede5e7c43e1ffb975130ae6 \ + --hash=sha256:ca233c64c6e40eaa6c66ef97058cdc80e8d0157a443655baa1b2966e812807ca \ + --hash=sha256:4474f8ea030b5127225b8894d626bb66c01cda098d47a2b0d3429b6700af9fd8 \ + --hash=sha256:326420cbb492172dec84b0f65c80942de6cedb5233c413dd824483989c000608 \ + --hash=sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7 +pathspec==0.5.3 \ + --hash=sha256:54478a66a360f4ebe4499c9235e4206fca5dec837b8e272d1ce37e0a626cc64d From 34f5922850f70e79bee7dd2e882971384b1ee7bc Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:26:13 -0400 Subject: [PATCH 109/166] Bug 1387862 - Lint taskcluster yaml files. r=dustin We should have CI Lint YAML files in the tree. MozReview-Commit-ID: L83j6SODA3w --HG-- extra : rebase_source : 2be273b518f3424d62f4a90cebe25a3c2833c8a0 --- taskcluster/.yamllint | 16 ++++++++++++++++ tools/lint/yaml.yml | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 taskcluster/.yamllint diff --git a/taskcluster/.yamllint b/taskcluster/.yamllint new file mode 100644 index 000000000000..b37a7238cb13 --- /dev/null +++ b/taskcluster/.yamllint @@ -0,0 +1,16 @@ +--- + +extends: default + +rules: + document-end: + present: false + # Checks currently failing + brackets: disable + commas: disable + comments: disable + comments-indentation: disable + document-start: disable + hyphens: disable + indentation: disable + line-length: disable diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml index 9bea664e58e4..224efc1312d9 100644 --- a/tools/lint/yaml.yml +++ b/tools/lint/yaml.yml @@ -1,5 +1,7 @@ yamllint: description: YAML linter + include: + - taskcluster extensions: ['yml', 'yaml'] type: external payload: yamllint_:lint From 0985529c394960195f77809dd93c3ddf1e813fce Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:35:27 -0400 Subject: [PATCH 110/166] Bug 1387862 - Lint taskcluster's cron.yml file, fixup lint errors. r=dustin We should have CI Lint YAML files in the tree. MozReview-Commit-ID: 758kdSddjJN --HG-- extra : rebase_source : f057b0ce281adb67a156235b051a371a252bd22c --- .cron.yml | 30 ++++++++++++++++-------------- tools/lint/yaml.yml | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.cron.yml b/.cron.yml index b0dbc4dcce11..28da8996c267 100644 --- a/.cron.yml +++ b/.cron.yml @@ -2,6 +2,8 @@ # `taskcluster/taskgraph/cron/schema.py`. For documentation, see # `taskcluster/docs/cron.rst`. +--- + jobs: - name: nightly-desktop job: @@ -13,10 +15,10 @@ jobs: - date when: by-project: - # Match buildbot starts for now - date: [{hour: 15, minute: 0}] - mozilla-central: [{hour: 10, minute: 0}] - # No default + # Match buildbot starts for now + date: [{hour: 15, minute: 0}] + mozilla-central: [{hour: 10, minute: 0}] + # No default - name: nightly-desktop-linux job: @@ -26,7 +28,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-desktop-osx job: @@ -36,7 +38,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-desktop-win32 job: @@ -56,7 +58,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-android job: @@ -67,11 +69,11 @@ jobs: - mozilla-central - date when: - by-project: - # Match buildbot starts for now - date: [{hour: 15, minute: 0}] - mozilla-central: [{hour: 10, minute: 0}] - # No default + by-project: + # Match buildbot starts for now + date: [{hour: 15, minute: 0}] + mozilla-central: [{hour: 10, minute: 0}] + # No default - name: nightly-mochitest-valgrind job: @@ -93,5 +95,5 @@ jobs: - mozilla-central when: by-project: - mozilla-central: [{hour: 10, minute: 0}] - # No default + mozilla-central: [{hour: 10, minute: 0}] + # No default diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml index 224efc1312d9..32d26ee51bc9 100644 --- a/tools/lint/yaml.yml +++ b/tools/lint/yaml.yml @@ -1,6 +1,7 @@ yamllint: description: YAML linter include: + - .cron.yml - taskcluster extensions: ['yml', 'yaml'] type: external From 906fda83978d6f638c5a8356ae3838818ad4f10c Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:43:04 -0400 Subject: [PATCH 111/166] Bug 1387862 - Lint python/mozlint yaml files. r=ahal We should have CI Lint YAML files in the tree. MozReview-Commit-ID: IMOKGhxKFJW --HG-- extra : rebase_source : 0ef71f24141a531833d48f2a305183dd808f00f5 --- python/mozlint/test/linters/badreturncode.yml | 1 + python/mozlint/test/linters/explicit_path.yml | 1 + python/mozlint/test/linters/external.yml | 1 + python/mozlint/test/linters/invalid_exclude.yml | 1 + python/mozlint/test/linters/invalid_extension.ym | 1 + python/mozlint/test/linters/invalid_include.yml | 1 + python/mozlint/test/linters/invalid_type.yml | 1 + python/mozlint/test/linters/missing_attrs.yml | 1 + python/mozlint/test/linters/raises.yml | 1 + python/mozlint/test/linters/regex.yml | 5 ++++- python/mozlint/test/linters/string.yml | 5 ++++- python/mozlint/test/linters/structured.yml | 1 + tools/lint/yaml.yml | 1 + 13 files changed, 19 insertions(+), 2 deletions(-) diff --git a/python/mozlint/test/linters/badreturncode.yml b/python/mozlint/test/linters/badreturncode.yml index 301d77583dc0..72abf83cc75c 100644 --- a/python/mozlint/test/linters/badreturncode.yml +++ b/python/mozlint/test/linters/badreturncode.yml @@ -1,3 +1,4 @@ +--- BadReturnCodeLinter: description: Returns an error code no matter what include: diff --git a/python/mozlint/test/linters/explicit_path.yml b/python/mozlint/test/linters/explicit_path.yml index 27cf3df7ffeb..80630518993a 100644 --- a/python/mozlint/test/linters/explicit_path.yml +++ b/python/mozlint/test/linters/explicit_path.yml @@ -1,3 +1,4 @@ +--- ExplicitPathLinter: description: Only lint a specific file name rule: no-foobar diff --git a/python/mozlint/test/linters/external.yml b/python/mozlint/test/linters/external.yml index e8e5f1bd40ab..574b8df4cb47 100644 --- a/python/mozlint/test/linters/external.yml +++ b/python/mozlint/test/linters/external.yml @@ -1,3 +1,4 @@ +--- ExternalLinter: description: It's bad to have the string foobar in js files. include: diff --git a/python/mozlint/test/linters/invalid_exclude.yml b/python/mozlint/test/linters/invalid_exclude.yml index c6e235f9e430..7231d2c14643 100644 --- a/python/mozlint/test/linters/invalid_exclude.yml +++ b/python/mozlint/test/linters/invalid_exclude.yml @@ -1,3 +1,4 @@ +--- BadExcludeLinter: description: Has an invalid exclude directive. exclude: [0, 1] # should be a list of strings diff --git a/python/mozlint/test/linters/invalid_extension.ym b/python/mozlint/test/linters/invalid_extension.ym index 7dac964fe66e..435fa10320f3 100644 --- a/python/mozlint/test/linters/invalid_extension.ym +++ b/python/mozlint/test/linters/invalid_extension.ym @@ -1,3 +1,4 @@ +--- BadExtensionLinter: description: Has an invalid file extension. type: string diff --git a/python/mozlint/test/linters/invalid_include.yml b/python/mozlint/test/linters/invalid_include.yml index 1d16db31627e..b76b3e6a61d7 100644 --- a/python/mozlint/test/linters/invalid_include.yml +++ b/python/mozlint/test/linters/invalid_include.yml @@ -1,3 +1,4 @@ +--- BadIncludeLinter: description: Has an invalid include directive. include: should be a list diff --git a/python/mozlint/test/linters/invalid_type.yml b/python/mozlint/test/linters/invalid_type.yml index fd47252f606f..29d82e541e1a 100644 --- a/python/mozlint/test/linters/invalid_type.yml +++ b/python/mozlint/test/linters/invalid_type.yml @@ -1,3 +1,4 @@ +--- BadTypeLinter: description: Has an invalid type. type: invalid diff --git a/python/mozlint/test/linters/missing_attrs.yml b/python/mozlint/test/linters/missing_attrs.yml index a62425582154..5abe15fcfc59 100644 --- a/python/mozlint/test/linters/missing_attrs.yml +++ b/python/mozlint/test/linters/missing_attrs.yml @@ -1,2 +1,3 @@ +--- MissingAttrsLinter: description: Missing type and payload diff --git a/python/mozlint/test/linters/raises.yml b/python/mozlint/test/linters/raises.yml index d9696f351a76..534896151373 100644 --- a/python/mozlint/test/linters/raises.yml +++ b/python/mozlint/test/linters/raises.yml @@ -1,3 +1,4 @@ +--- RaisesLinter: description: Raises an exception type: external diff --git a/python/mozlint/test/linters/regex.yml b/python/mozlint/test/linters/regex.yml index 570bbd98080b..5b0f11bd830b 100644 --- a/python/mozlint/test/linters/regex.yml +++ b/python/mozlint/test/linters/regex.yml @@ -1,5 +1,8 @@ +--- RegexLinter: - description: Make sure the string foobar never appears in a js variable file because it is bad. + description: >- + Make sure the string foobar never appears in a js variable + file because it is bad. rule: no-foobar include: - '**/*.js' diff --git a/python/mozlint/test/linters/string.yml b/python/mozlint/test/linters/string.yml index 2253a3bbd0e4..1202c5728b33 100644 --- a/python/mozlint/test/linters/string.yml +++ b/python/mozlint/test/linters/string.yml @@ -1,5 +1,8 @@ +--- StringLinter: - description: Make sure the string foobar never appears in browser js files because it is bad + description: >- + Make sure the string foobar never appears in browser js + files because it is bad rule: no-foobar include: - '**/*.js' diff --git a/python/mozlint/test/linters/structured.yml b/python/mozlint/test/linters/structured.yml index a2cbe56ecefa..01ef447ee3bd 100644 --- a/python/mozlint/test/linters/structured.yml +++ b/python/mozlint/test/linters/structured.yml @@ -1,3 +1,4 @@ +--- StructuredLinter: description: "It's bad to have the string foobar in js files." include: diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml index 32d26ee51bc9..a4ad5547f1a1 100644 --- a/tools/lint/yaml.yml +++ b/tools/lint/yaml.yml @@ -2,6 +2,7 @@ yamllint: description: YAML linter include: - .cron.yml + - python/mozlint/ - taskcluster extensions: ['yml', 'yaml'] type: external From a37b9ce0f23b222cdaeb2637dc85c59ad7d9ccca Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:44:41 -0400 Subject: [PATCH 112/166] Bug 1387862 - Lint NSS's taskcluster.yml. r=dustin We should have CI Lint YAML files in the tree. MozReview-Commit-ID: ATX5IOK747y --HG-- extra : rebase_source : 493c6c762e3b26f1295205c0300df8b0cd87bc7b --- tools/lint/yaml.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml index a4ad5547f1a1..cd11e0f06fc1 100644 --- a/tools/lint/yaml.yml +++ b/tools/lint/yaml.yml @@ -3,6 +3,7 @@ yamllint: include: - .cron.yml - python/mozlint/ + - security/nss/.taskcluster.yml - taskcluster extensions: ['yml', 'yaml'] type: external From 9eadced0828e314a529d21665a141dc22b432a7b Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:47:03 -0400 Subject: [PATCH 113/166] Bug 1387862 - Lint the linter config yaml files themselves. r=ahal We should have CI Lint YAML files in the tree. MozReview-Commit-ID: F8hTBerSNIj --HG-- extra : rebase_source : b3b420eb4f66e448e41de4b556c200e1bd590094 --- tools/lint/eslint.yml | 1 + tools/lint/flake8.yml | 1 + tools/lint/wpt.yml | 1 + tools/lint/wpt_manifest.yml | 1 + tools/lint/yaml.yml | 3 +++ 5 files changed, 7 insertions(+) diff --git a/tools/lint/eslint.yml b/tools/lint/eslint.yml index 09115da23960..f3afb27cbdab 100644 --- a/tools/lint/eslint.yml +++ b/tools/lint/eslint.yml @@ -1,3 +1,4 @@ +--- eslint: description: JavaScript linter # ESLint infra handles its own path filtering, so just include cwd diff --git a/tools/lint/flake8.yml b/tools/lint/flake8.yml index 1c963aa257c0..2a9be33db3bc 100644 --- a/tools/lint/flake8.yml +++ b/tools/lint/flake8.yml @@ -1,3 +1,4 @@ +--- flake8: description: Python linter include: diff --git a/tools/lint/wpt.yml b/tools/lint/wpt.yml index 1553f7793b23..e00cb4bee667 100644 --- a/tools/lint/wpt.yml +++ b/tools/lint/wpt.yml @@ -1,3 +1,4 @@ +--- wpt: description: web-platform-tests lint include: diff --git a/tools/lint/wpt_manifest.yml b/tools/lint/wpt_manifest.yml index 610a0096796a..bad83164a773 100644 --- a/tools/lint/wpt_manifest.yml +++ b/tools/lint/wpt_manifest.yml @@ -1,3 +1,4 @@ +--- wpt_manifest: description: web-platform-tests manifest lint include: diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml index cd11e0f06fc1..3fb3d6755629 100644 --- a/tools/lint/yaml.yml +++ b/tools/lint/yaml.yml @@ -1,3 +1,4 @@ +--- yamllint: description: YAML linter include: @@ -5,6 +6,8 @@ yamllint: - python/mozlint/ - security/nss/.taskcluster.yml - taskcluster + - testing/mozharness + - tools extensions: ['yml', 'yaml'] type: external payload: yamllint_:lint From c363646e59973583b8f267e149d9c58a2b10e581 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 13:52:24 -0400 Subject: [PATCH 114/166] Bug 1387862 - Add yaml lint to the taskgraph. r=ahal,dustin We should have CI Lint YAML files in the tree. MozReview-Commit-ID: GN5pOJCXvnz --HG-- extra : rebase_source : 15509426d82ccbe647172274f9d6d80aa913bdf6 --- taskcluster/ci/source-test/mozlint.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/taskcluster/ci/source-test/mozlint.yml b/taskcluster/ci/source-test/mozlint.yml index f11bb4c16cd4..4928534b7e93 100644 --- a/taskcluster/ci/source-test/mozlint.yml +++ b/taskcluster/ci/source-test/mozlint.yml @@ -57,6 +57,28 @@ mozlint-flake8: - 'python/mozlint/**' - 'tools/lint/**' +mozlint-yaml: + description: yamllint run over the gecko codebase + platform: lint/opt + treeherder: + symbol: yaml + kind: test + tier: 1 + worker-type: aws-provisioner-v1/gecko-t-linux-xlarge + worker: + docker-image: {in-tree: "lint"} + max-run-time: 1800 + run: + using: mach + mach: lint -l yamllint -f treeherder + when: + files-changed: + - '**/*.yml' + - '**/*.yaml' + - '**/.ymllint' + - 'python/mozlint/**' + - 'tools/lint/**' + wptlint-gecko: description: web-platform-tests linter platform: lint/opt From edcb5a7dd904265cb26d5fa986fa5e2f0edaf887 Mon Sep 17 00:00:00 2001 From: James Cheng Date: Thu, 10 Aug 2017 01:39:49 +0800 Subject: [PATCH 115/166] Bug 1388822 - Skip test_playback_hls.html lower than API level 20. r=alwu MozReview-Commit-ID: 3wzzNr5xNjB --HG-- extra : rebase_source : 30037d1aabd157d8606976b56c769d91e20b4a3f --- dom/media/test/mochitest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index df20b61956f0..27e13276d099 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -1213,7 +1213,7 @@ skip-if = (os == 'win' || android_version == '19') # bug 1374189 # HLS is only supported on Fennec with API level >= 16 # TODO: This test is similar to test_playback.html, will remove the # redundant code once test_playback.html is enabled on Fennec. -skip-if = toolkit != 'android' || android_version < '16' +skip-if = toolkit != 'android' || android_version < '20' #bug 1388633 tags = hls [test_hls_player_independency.html] From 24396489e3ed2cd1db1976589192162983553e81 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 9 Aug 2017 21:31:30 -0400 Subject: [PATCH 116/166] Backed out 7 changesets (bug 1387862) for yaml linting failures. Backed out changeset 63f87f6db7d6 (bug 1387862) Backed out changeset a85b7e7d9f24 (bug 1387862) Backed out changeset 3713ea9672e8 (bug 1387862) Backed out changeset 22c1094e387f (bug 1387862) Backed out changeset e0bfb35b0eec (bug 1387862) Backed out changeset 5bb5dc7655ec (bug 1387862) Backed out changeset cc4c01794114 (bug 1387862) --- .cron.yml | 30 ++-- python/mozlint/test/linters/badreturncode.yml | 1 - python/mozlint/test/linters/explicit_path.yml | 1 - python/mozlint/test/linters/external.yml | 1 - .../mozlint/test/linters/invalid_exclude.yml | 1 - .../mozlint/test/linters/invalid_extension.ym | 1 - .../mozlint/test/linters/invalid_include.yml | 1 - python/mozlint/test/linters/invalid_type.yml | 1 - python/mozlint/test/linters/missing_attrs.yml | 1 - python/mozlint/test/linters/raises.yml | 1 - python/mozlint/test/linters/regex.yml | 5 +- python/mozlint/test/linters/string.yml | 5 +- python/mozlint/test/linters/structured.yml | 1 - taskcluster/.yamllint | 16 -- taskcluster/ci/source-test/mozlint.yml | 22 --- tools/lint/eslint.yml | 1 - tools/lint/flake8.yml | 1 - tools/lint/wpt.yml | 1 - tools/lint/wpt_manifest.yml | 1 - tools/lint/yaml.yml | 13 -- tools/lint/yamllint_/__init__.py | 154 ------------------ .../lint/yamllint_/yamllint_requirements.txt | 21 --- 22 files changed, 16 insertions(+), 264 deletions(-) delete mode 100644 taskcluster/.yamllint delete mode 100644 tools/lint/yaml.yml delete mode 100644 tools/lint/yamllint_/__init__.py delete mode 100644 tools/lint/yamllint_/yamllint_requirements.txt diff --git a/.cron.yml b/.cron.yml index 28da8996c267..b0dbc4dcce11 100644 --- a/.cron.yml +++ b/.cron.yml @@ -2,8 +2,6 @@ # `taskcluster/taskgraph/cron/schema.py`. For documentation, see # `taskcluster/docs/cron.rst`. ---- - jobs: - name: nightly-desktop job: @@ -15,10 +13,10 @@ jobs: - date when: by-project: - # Match buildbot starts for now - date: [{hour: 15, minute: 0}] - mozilla-central: [{hour: 10, minute: 0}] - # No default + # Match buildbot starts for now + date: [{hour: 15, minute: 0}] + mozilla-central: [{hour: 10, minute: 0}] + # No default - name: nightly-desktop-linux job: @@ -28,7 +26,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-desktop-osx job: @@ -38,7 +36,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-desktop-win32 job: @@ -58,7 +56,7 @@ jobs: run-on-projects: - mozilla-central - date - when: [] # never (hook only) + when: [] # never (hook only) - name: nightly-android job: @@ -69,11 +67,11 @@ jobs: - mozilla-central - date when: - by-project: - # Match buildbot starts for now - date: [{hour: 15, minute: 0}] - mozilla-central: [{hour: 10, minute: 0}] - # No default + by-project: + # Match buildbot starts for now + date: [{hour: 15, minute: 0}] + mozilla-central: [{hour: 10, minute: 0}] + # No default - name: nightly-mochitest-valgrind job: @@ -95,5 +93,5 @@ jobs: - mozilla-central when: by-project: - mozilla-central: [{hour: 10, minute: 0}] - # No default + mozilla-central: [{hour: 10, minute: 0}] + # No default diff --git a/python/mozlint/test/linters/badreturncode.yml b/python/mozlint/test/linters/badreturncode.yml index 72abf83cc75c..301d77583dc0 100644 --- a/python/mozlint/test/linters/badreturncode.yml +++ b/python/mozlint/test/linters/badreturncode.yml @@ -1,4 +1,3 @@ ---- BadReturnCodeLinter: description: Returns an error code no matter what include: diff --git a/python/mozlint/test/linters/explicit_path.yml b/python/mozlint/test/linters/explicit_path.yml index 80630518993a..27cf3df7ffeb 100644 --- a/python/mozlint/test/linters/explicit_path.yml +++ b/python/mozlint/test/linters/explicit_path.yml @@ -1,4 +1,3 @@ ---- ExplicitPathLinter: description: Only lint a specific file name rule: no-foobar diff --git a/python/mozlint/test/linters/external.yml b/python/mozlint/test/linters/external.yml index 574b8df4cb47..e8e5f1bd40ab 100644 --- a/python/mozlint/test/linters/external.yml +++ b/python/mozlint/test/linters/external.yml @@ -1,4 +1,3 @@ ---- ExternalLinter: description: It's bad to have the string foobar in js files. include: diff --git a/python/mozlint/test/linters/invalid_exclude.yml b/python/mozlint/test/linters/invalid_exclude.yml index 7231d2c14643..c6e235f9e430 100644 --- a/python/mozlint/test/linters/invalid_exclude.yml +++ b/python/mozlint/test/linters/invalid_exclude.yml @@ -1,4 +1,3 @@ ---- BadExcludeLinter: description: Has an invalid exclude directive. exclude: [0, 1] # should be a list of strings diff --git a/python/mozlint/test/linters/invalid_extension.ym b/python/mozlint/test/linters/invalid_extension.ym index 435fa10320f3..7dac964fe66e 100644 --- a/python/mozlint/test/linters/invalid_extension.ym +++ b/python/mozlint/test/linters/invalid_extension.ym @@ -1,4 +1,3 @@ ---- BadExtensionLinter: description: Has an invalid file extension. type: string diff --git a/python/mozlint/test/linters/invalid_include.yml b/python/mozlint/test/linters/invalid_include.yml index b76b3e6a61d7..1d16db31627e 100644 --- a/python/mozlint/test/linters/invalid_include.yml +++ b/python/mozlint/test/linters/invalid_include.yml @@ -1,4 +1,3 @@ ---- BadIncludeLinter: description: Has an invalid include directive. include: should be a list diff --git a/python/mozlint/test/linters/invalid_type.yml b/python/mozlint/test/linters/invalid_type.yml index 29d82e541e1a..fd47252f606f 100644 --- a/python/mozlint/test/linters/invalid_type.yml +++ b/python/mozlint/test/linters/invalid_type.yml @@ -1,4 +1,3 @@ ---- BadTypeLinter: description: Has an invalid type. type: invalid diff --git a/python/mozlint/test/linters/missing_attrs.yml b/python/mozlint/test/linters/missing_attrs.yml index 5abe15fcfc59..a62425582154 100644 --- a/python/mozlint/test/linters/missing_attrs.yml +++ b/python/mozlint/test/linters/missing_attrs.yml @@ -1,3 +1,2 @@ ---- MissingAttrsLinter: description: Missing type and payload diff --git a/python/mozlint/test/linters/raises.yml b/python/mozlint/test/linters/raises.yml index 534896151373..d9696f351a76 100644 --- a/python/mozlint/test/linters/raises.yml +++ b/python/mozlint/test/linters/raises.yml @@ -1,4 +1,3 @@ ---- RaisesLinter: description: Raises an exception type: external diff --git a/python/mozlint/test/linters/regex.yml b/python/mozlint/test/linters/regex.yml index 5b0f11bd830b..570bbd98080b 100644 --- a/python/mozlint/test/linters/regex.yml +++ b/python/mozlint/test/linters/regex.yml @@ -1,8 +1,5 @@ ---- RegexLinter: - description: >- - Make sure the string foobar never appears in a js variable - file because it is bad. + description: Make sure the string foobar never appears in a js variable file because it is bad. rule: no-foobar include: - '**/*.js' diff --git a/python/mozlint/test/linters/string.yml b/python/mozlint/test/linters/string.yml index 1202c5728b33..2253a3bbd0e4 100644 --- a/python/mozlint/test/linters/string.yml +++ b/python/mozlint/test/linters/string.yml @@ -1,8 +1,5 @@ ---- StringLinter: - description: >- - Make sure the string foobar never appears in browser js - files because it is bad + description: Make sure the string foobar never appears in browser js files because it is bad rule: no-foobar include: - '**/*.js' diff --git a/python/mozlint/test/linters/structured.yml b/python/mozlint/test/linters/structured.yml index 01ef447ee3bd..a2cbe56ecefa 100644 --- a/python/mozlint/test/linters/structured.yml +++ b/python/mozlint/test/linters/structured.yml @@ -1,4 +1,3 @@ ---- StructuredLinter: description: "It's bad to have the string foobar in js files." include: diff --git a/taskcluster/.yamllint b/taskcluster/.yamllint deleted file mode 100644 index b37a7238cb13..000000000000 --- a/taskcluster/.yamllint +++ /dev/null @@ -1,16 +0,0 @@ ---- - -extends: default - -rules: - document-end: - present: false - # Checks currently failing - brackets: disable - commas: disable - comments: disable - comments-indentation: disable - document-start: disable - hyphens: disable - indentation: disable - line-length: disable diff --git a/taskcluster/ci/source-test/mozlint.yml b/taskcluster/ci/source-test/mozlint.yml index 4928534b7e93..f11bb4c16cd4 100644 --- a/taskcluster/ci/source-test/mozlint.yml +++ b/taskcluster/ci/source-test/mozlint.yml @@ -57,28 +57,6 @@ mozlint-flake8: - 'python/mozlint/**' - 'tools/lint/**' -mozlint-yaml: - description: yamllint run over the gecko codebase - platform: lint/opt - treeherder: - symbol: yaml - kind: test - tier: 1 - worker-type: aws-provisioner-v1/gecko-t-linux-xlarge - worker: - docker-image: {in-tree: "lint"} - max-run-time: 1800 - run: - using: mach - mach: lint -l yamllint -f treeherder - when: - files-changed: - - '**/*.yml' - - '**/*.yaml' - - '**/.ymllint' - - 'python/mozlint/**' - - 'tools/lint/**' - wptlint-gecko: description: web-platform-tests linter platform: lint/opt diff --git a/tools/lint/eslint.yml b/tools/lint/eslint.yml index f3afb27cbdab..09115da23960 100644 --- a/tools/lint/eslint.yml +++ b/tools/lint/eslint.yml @@ -1,4 +1,3 @@ ---- eslint: description: JavaScript linter # ESLint infra handles its own path filtering, so just include cwd diff --git a/tools/lint/flake8.yml b/tools/lint/flake8.yml index 2a9be33db3bc..1c963aa257c0 100644 --- a/tools/lint/flake8.yml +++ b/tools/lint/flake8.yml @@ -1,4 +1,3 @@ ---- flake8: description: Python linter include: diff --git a/tools/lint/wpt.yml b/tools/lint/wpt.yml index e00cb4bee667..1553f7793b23 100644 --- a/tools/lint/wpt.yml +++ b/tools/lint/wpt.yml @@ -1,4 +1,3 @@ ---- wpt: description: web-platform-tests lint include: diff --git a/tools/lint/wpt_manifest.yml b/tools/lint/wpt_manifest.yml index bad83164a773..610a0096796a 100644 --- a/tools/lint/wpt_manifest.yml +++ b/tools/lint/wpt_manifest.yml @@ -1,4 +1,3 @@ ---- wpt_manifest: description: web-platform-tests manifest lint include: diff --git a/tools/lint/yaml.yml b/tools/lint/yaml.yml deleted file mode 100644 index 3fb3d6755629..000000000000 --- a/tools/lint/yaml.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -yamllint: - description: YAML linter - include: - - .cron.yml - - python/mozlint/ - - security/nss/.taskcluster.yml - - taskcluster - - testing/mozharness - - tools - extensions: ['yml', 'yaml'] - type: external - payload: yamllint_:lint diff --git a/tools/lint/yamllint_/__init__.py b/tools/lint/yamllint_/__init__.py deleted file mode 100644 index 16fe34a61320..000000000000 --- a/tools/lint/yamllint_/__init__.py +++ /dev/null @@ -1,154 +0,0 @@ -# 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/. - -import re -import os -import signal -import subprocess - -import which -from mozprocess import ProcessHandlerMixin - -from mozlint import result - - -here = os.path.abspath(os.path.dirname(__file__)) -YAMLLINT_REQUIREMENTS_PATH = os.path.join(here, 'yamllint_requirements.txt') - - -YAMLLINT_INSTALL_ERROR = """ -Unable to install correct version of yamllint -Try to install it manually with: - $ pip install -U --require-hashes -r {} -""".strip().format(YAMLLINT_REQUIREMENTS_PATH) - -YAMLLINT_FORMAT_REGEX = re.compile(r'(.*):(.*):(.*): \[(error|warning)\] (.*) \((.*)\)$') - -results = [] - - -class YAMLLintProcess(ProcessHandlerMixin): - def __init__(self, config, *args, **kwargs): - self.config = config - kwargs['processOutputLine'] = [self.process_line] - ProcessHandlerMixin.__init__(self, *args, **kwargs) - - def process_line(self, line): - try: - match = YAMLLINT_FORMAT_REGEX.match(line) - abspath, line, col, level, message, code = match.groups() - except AttributeError: - print('Unable to match yaml regex against output: {}'.format(line)) - return - - res = {'path': os.path.relpath(abspath, self.config['root']), - 'message': message, - 'level': level, - 'lineno': line, - 'column': col, - 'rule': code, - } - - results.append(result.from_config(self.config, **res)) - - def run(self, *args, **kwargs): - # protect against poor SIGINT handling. Handle it here instead - # so we can kill the process without a cryptic traceback. - orig = signal.signal(signal.SIGINT, signal.SIG_IGN) - ProcessHandlerMixin.run(self, *args, **kwargs) - signal.signal(signal.SIGINT, orig) - - -def get_yamllint_binary(): - """ - Returns the path of the first yamllint binary available - if not found returns None - """ - binary = os.environ.get('YAMLLINT') - if binary: - return binary - - try: - return which.which('yamllint') - except which.WhichError: - return None - - -def _run_pip(*args): - """ - Helper function that runs pip with subprocess - """ - try: - subprocess.check_output(['pip'] + list(args), - stderr=subprocess.STDOUT) - return True - except subprocess.CalledProcessError as e: - print(e.output) - return False - - -def reinstall_yamllint(): - """ - Try to install yamllint at the target version, returns True on success - otherwise prints the otuput of the pip command and returns False - """ - if _run_pip('install', '-U', - '--require-hashes', '-r', - YAMLLINT_REQUIREMENTS_PATH): - return True - - return False - - -def run_process(config, cmd): - proc = YAMLLintProcess(config, cmd) - proc.run() - try: - proc.wait() - except KeyboardInterrupt: - proc.kill() - - -def gen_yamllint_args(cmdargs, paths=None, conf_file=None): - args = cmdargs[:] - if isinstance(paths, basestring): - paths = [paths] - if conf_file: - return args + ['-c', conf_file] + paths - return args + paths - - -def lint(files, config, **lintargs): - - if not reinstall_yamllint(): - print(YAMLLINT_INSTALL_ERROR) - return 1 - - binary = get_yamllint_binary() - - cmdargs = [ - binary, - '-f', 'parsable' - ] - - config = config.copy() - config['root'] = lintargs['root'] - - # Run any paths with a .yamllint file in the directory separately so - # it gets picked up. This means only .yamllint files that live in - # directories that are explicitly included will be considered. - no_config = [] - for f in files: - yamllint_config = os.path.join(f, '.yamllint') - if not os.path.isfile(yamllint_config): - no_config.append(f) - continue - run_process(config, - gen_yamllint_args(cmdargs, conf_file=yamllint_config, paths=f)) - - if no_config: - run_process(config, - gen_yamllint_args(cmdargs, paths=no_config)) - - return results diff --git a/tools/lint/yamllint_/yamllint_requirements.txt b/tools/lint/yamllint_/yamllint_requirements.txt deleted file mode 100644 index b442a8f2ea70..000000000000 --- a/tools/lint/yamllint_/yamllint_requirements.txt +++ /dev/null @@ -1,21 +0,0 @@ -yamllint==1.8.1 \ - --hash=sha256:806b21828ca92fd6e9f20d8eccfa53035e38041854bb4d1b666f271a7788dbcf \ - --hash=sha256:048743567ca9511e19222233ebb53795586a2cede07b79e801577e0a9b4f173c -PyYAML==3.12 \ - --hash=sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f \ - --hash=sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736 \ - --hash=sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269 \ - --hash=sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8 \ - --hash=sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4 \ - --hash=sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1 \ - --hash=sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab \ - --hash=sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab \ - --hash=sha256:5f84523c076ad14ff5e6c037fe1c89a7f73a3e04cf0377cb4d017014976433f3 \ - --hash=sha256:0c507b7f74b3d2dd4d1322ec8a94794927305ab4cebbe89cc47fe5e81541e6e8 \ - --hash=sha256:b4c423ab23291d3945ac61346feeb9a0dc4184999ede5e7c43e1ffb975130ae6 \ - --hash=sha256:ca233c64c6e40eaa6c66ef97058cdc80e8d0157a443655baa1b2966e812807ca \ - --hash=sha256:4474f8ea030b5127225b8894d626bb66c01cda098d47a2b0d3429b6700af9fd8 \ - --hash=sha256:326420cbb492172dec84b0f65c80942de6cedb5233c413dd824483989c000608 \ - --hash=sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7 -pathspec==0.5.3 \ - --hash=sha256:54478a66a360f4ebe4499c9235e4206fca5dec837b8e272d1ce37e0a626cc64d From 13717056a2f0cdc68899e40dc15023dc9e452e02 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 9 Aug 2017 19:28:07 -0500 Subject: [PATCH 117/166] servo: Merge #18017 - style: Move all origin-specific cascade data to PerOriginCascadeData (from heycam:split-cascade); r=emilio This is a preliminary refactoring in preparation for only rebuilding cascade data for origins that have a change. https://bugzilla.mozilla.org/show_bug.cgi?id=1382925 --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: ca14848711884a15a352ec5453df3d83574036a5 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : da603047dcb33bc29a2d5e4a01c2460b5e421400 --- servo/components/selectors/bloom.rs | 247 ++++++++++++----- servo/components/style/animation.rs | 4 +- servo/components/style/context.rs | 12 +- .../invalidation/element/invalidation_map.rs | 3 +- .../style/invalidation/element/invalidator.rs | 12 +- servo/components/style/stylist.rs | 262 ++++++++++-------- servo/ports/geckolib/glue.rs | 2 +- 7 files changed, 345 insertions(+), 197 deletions(-) diff --git a/servo/components/selectors/bloom.rs b/servo/components/selectors/bloom.rs index 0e8290fc8c92..2b96e4f51f87 100644 --- a/servo/components/selectors/bloom.rs +++ b/servo/components/selectors/bloom.rs @@ -2,9 +2,11 @@ * 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/. */ -//! Simple counting bloom filters. +//! Counting and non-counting Bloom filters tuned for use as ancestor filters +//! for selector matching. use fnv::FnvHasher; +use std::fmt::{self, Debug}; use std::hash::{Hash, Hasher}; // The top 8 bits of the 32-bit hash value are not used by the bloom filter. @@ -15,9 +17,17 @@ const KEY_SIZE: usize = 12; const ARRAY_SIZE: usize = 1 << KEY_SIZE; const KEY_MASK: u32 = (1 << KEY_SIZE) - 1; -/// A counting Bloom filter with 8-bit counters. For now we assume -/// that having two hash functions is enough, but we may revisit that -/// decision later. +/// A counting Bloom filter with 8-bit counters. +pub type BloomFilter = CountingBloomFilter; + +/// A non-counting Bloom filter. +/// +/// Effectively a counting Bloom filter with 1-bit counters. +pub type NonCountingBloomFilter = CountingBloomFilter; + +/// A counting Bloom filter with parameterized storage to handle +/// counters of different sizes. For now we assume that having two hash +/// functions is enough, but we may revisit that decision later. /// /// The filter uses an array with 2**KeySize entries. /// @@ -61,58 +71,30 @@ const KEY_MASK: u32 = (1 << KEY_SIZE) - 1; /// Similarly, using a KeySize of 10 would lead to a 4% false /// positive rate for N == 100 and to quite bad false positive /// rates for larger N. -pub struct BloomFilter { - counters: [u8; ARRAY_SIZE], +#[derive(Clone)] +pub struct CountingBloomFilter where S: BloomStorage { + storage: S, } -impl Clone for BloomFilter { - #[inline] - fn clone(&self) -> BloomFilter { - BloomFilter { - counters: self.counters, - } - } -} - -impl BloomFilter { +impl CountingBloomFilter where S: BloomStorage { /// Creates a new bloom filter. #[inline] - pub fn new() -> BloomFilter { - BloomFilter { - counters: [0; ARRAY_SIZE], + pub fn new() -> Self { + CountingBloomFilter { + storage: Default::default(), } } - #[inline] - fn first_slot(&self, hash: u32) -> &u8 { - &self.counters[hash1(hash) as usize] - } - - #[inline] - fn first_mut_slot(&mut self, hash: u32) -> &mut u8 { - &mut self.counters[hash1(hash) as usize] - } - - #[inline] - fn second_slot(&self, hash: u32) -> &u8 { - &self.counters[hash2(hash) as usize] - } - - #[inline] - fn second_mut_slot(&mut self, hash: u32) -> &mut u8 { - &mut self.counters[hash2(hash) as usize] - } - #[inline] pub fn clear(&mut self) { - self.counters = [0; ARRAY_SIZE] + self.storage = Default::default(); } // Slow linear accessor to make sure the bloom filter is zeroed. This should // never be used in release builds. #[cfg(debug_assertions)] pub fn is_zeroed(&self) -> bool { - self.counters.iter().all(|x| *x == 0) + self.storage.is_zeroed() } #[cfg(not(debug_assertions))] @@ -122,18 +104,8 @@ impl BloomFilter { #[inline] pub fn insert_hash(&mut self, hash: u32) { - { - let slot1 = self.first_mut_slot(hash); - if !full(slot1) { - *slot1 += 1 - } - } - { - let slot2 = self.second_mut_slot(hash); - if !full(slot2) { - *slot2 += 1 - } - } + self.storage.adjust_first_slot(hash, true); + self.storage.adjust_second_slot(hash, true); } /// Inserts an item into the bloom filter. @@ -144,18 +116,8 @@ impl BloomFilter { #[inline] pub fn remove_hash(&mut self, hash: u32) { - { - let slot1 = self.first_mut_slot(hash); - if !full(slot1) { - *slot1 -= 1 - } - } - { - let slot2 = self.second_mut_slot(hash); - if !full(slot2) { - *slot2 -= 1 - } - } + self.storage.adjust_first_slot(hash, false); + self.storage.adjust_second_slot(hash, false); } /// Removes an item from the bloom filter. @@ -166,7 +128,8 @@ impl BloomFilter { #[inline] pub fn might_contain_hash(&self, hash: u32) -> bool { - *self.first_slot(hash) != 0 && *self.second_slot(hash) != 0 + !self.storage.first_slot_is_empty(hash) && + !self.storage.second_slot_is_empty(hash) } /// Check whether the filter might contain an item. This can @@ -179,9 +142,147 @@ impl BloomFilter { } } -#[inline] -fn full(slot: &u8) -> bool { - *slot == 0xff +impl Debug for CountingBloomFilter where S: BloomStorage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut slots_used = 0; + for i in 0..ARRAY_SIZE { + if !self.storage.slot_is_empty(i) { + slots_used += 1; + } + } + write!(f, "BloomFilter({}/{})", slots_used, ARRAY_SIZE) + } +} + +pub trait BloomStorage : Clone + Default { + fn slot_is_empty(&self, index: usize) -> bool; + fn adjust_slot(&mut self, index: usize, increment: bool); + fn is_zeroed(&self) -> bool; + + #[inline] + fn first_slot_is_empty(&self, hash: u32) -> bool { + self.slot_is_empty(Self::first_slot_index(hash)) + } + + #[inline] + fn second_slot_is_empty(&self, hash: u32) -> bool { + self.slot_is_empty(Self::second_slot_index(hash)) + } + + #[inline] + fn adjust_first_slot(&mut self, hash: u32, increment: bool) { + self.adjust_slot(Self::first_slot_index(hash), increment) + } + + #[inline] + fn adjust_second_slot(&mut self, hash: u32, increment: bool) { + self.adjust_slot(Self::second_slot_index(hash), increment) + } + + #[inline] + fn first_slot_index(hash: u32) -> usize { + hash1(hash) as usize + } + + #[inline] + fn second_slot_index(hash: u32) -> usize { + hash2(hash) as usize + } +} + +/// Storage class for a CountingBloomFilter that has 8-bit counters. +pub struct BloomStorageU8 { + counters: [u8; ARRAY_SIZE], +} + +impl BloomStorage for BloomStorageU8 { + #[inline] + fn adjust_slot(&mut self, index: usize, increment: bool) { + let slot = &mut self.counters[index]; + if *slot != 0xff { // full + if increment { + *slot += 1; + } else { + *slot -= 1; + } + } + } + + #[inline] + fn slot_is_empty(&self, index: usize) -> bool { + self.counters[index] == 0 + } + + #[inline] + fn is_zeroed(&self) -> bool { + self.counters.iter().all(|x| *x == 0) + } +} + +impl Default for BloomStorageU8 { + fn default() -> Self { + BloomStorageU8 { + counters: [0; ARRAY_SIZE], + } + } +} + +impl Clone for BloomStorageU8 { + fn clone(&self) -> Self { + BloomStorageU8 { + counters: self.counters, + } + } +} + +/// Storage class for a CountingBloomFilter that has 1-bit counters. +pub struct BloomStorageBool { + counters: [u8; ARRAY_SIZE / 8], +} + +impl BloomStorage for BloomStorageBool { + #[inline] + fn adjust_slot(&mut self, index: usize, increment: bool) { + let bit = 1 << (index % 8); + let byte = &mut self.counters[index / 8]; + + // Since we have only one bit for storage, decrementing it + // should never do anything. Assert against an accidental + // decrementing of a bit that was never set. + assert!(increment || (*byte & bit) != 0, + "should not decrement if slot is already false"); + + if increment { + *byte |= bit; + } + } + + #[inline] + fn slot_is_empty(&self, index: usize) -> bool { + let bit = 1 << (index % 8); + (self.counters[index / 8] & bit) == 0 + } + + #[inline] + fn is_zeroed(&self) -> bool { + self.counters.iter().all(|x| *x == 0) + } +} + +impl Default for BloomStorageBool { + fn default() -> Self { + BloomStorageBool { + counters: [0; ARRAY_SIZE / 8], + } + } +} + +impl Clone for BloomStorageBool { + fn clone(&self) -> Self { + BloomStorageBool { + counters: self.counters, + } + } } fn hash(elem: &T) -> u32 { @@ -203,8 +304,16 @@ fn hash2(hash: u32) -> u32 { #[test] fn create_and_insert_some_stuff() { + use std::mem::transmute; + let mut bf = BloomFilter::new(); + // Statically assert that ARRAY_SIZE is a multiple of 8, which + // BloomStorageBool relies on. + unsafe { + transmute::<[u8; ARRAY_SIZE % 8], [u8; 0]>([]); + } + for i in 0_usize .. 1000 { bf.insert(&i); } diff --git a/servo/components/style/animation.rs b/servo/components/style/animation.rs index 69b94edb5808..c1a49fca7a12 100644 --- a/servo/components/style/animation.rs +++ b/servo/components/style/animation.rs @@ -533,7 +533,7 @@ pub fn maybe_start_animations(context: &SharedStyleContext, continue } - if let Some(ref anim) = context.stylist.animations().get(name) { + if let Some(ref anim) = context.stylist.get_animation(name) { debug!("maybe_start_animations: animation {} found", name); // If this animation doesn't have any keyframe, we can just continue @@ -637,7 +637,7 @@ pub fn update_style_for_animation(context: &SharedStyleContext, KeyframesRunningState::Paused(progress) => started_at + duration * progress, }; - let animation = match context.stylist.animations().get(name) { + let animation = match context.stylist.get_animation(name) { None => { warn!("update_style_for_animation: Animation {:?} not found", name); return; diff --git a/servo/components/style/context.rs b/servo/components/style/context.rs index 7ae849d07285..07c5bb073719 100644 --- a/servo/components/style/context.rs +++ b/servo/components/style/context.rs @@ -388,16 +388,16 @@ impl TraversalStatistics { D: DomTraversal, { let threshold = traversal.shared_context().options.style_statistics_threshold; + let stylist = traversal.shared_context().stylist; self.is_parallel = Some(traversal.is_parallel()); self.is_large = Some(self.elements_traversed as usize >= threshold); self.traversal_time_ms = (time::precise_time_s() - start) * 1000.0; - self.selectors = traversal.shared_context().stylist.num_selectors() as u32; - self.revalidation_selectors = traversal.shared_context().stylist.num_revalidation_selectors() as u32; - self.dependency_selectors = - traversal.shared_context().stylist.invalidation_map().len() as u32; - self.declarations = traversal.shared_context().stylist.num_declarations() as u32; - self.stylist_rebuilds = traversal.shared_context().stylist.num_rebuilds() as u32; + self.selectors = stylist.num_selectors() as u32; + self.revalidation_selectors = stylist.num_revalidation_selectors() as u32; + self.dependency_selectors = stylist.num_invalidations() as u32; + self.declarations = stylist.num_declarations() as u32; + self.stylist_rebuilds = stylist.num_rebuilds() as u32; } /// Returns whether this traversal is 'large' in order to avoid console spam diff --git a/servo/components/style/invalidation/element/invalidation_map.rs b/servo/components/style/invalidation/element/invalidation_map.rs index e5c6c63bfcee..81f966a5df32 100644 --- a/servo/components/style/invalidation/element/invalidation_map.rs +++ b/servo/components/style/invalidation/element/invalidation_map.rs @@ -109,7 +109,7 @@ impl SelectorMapEntry for Dependency { /// The same, but for state selectors, which can track more exactly what state /// do they track. -#[derive(Clone)] +#[derive(Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct StateDependency { /// The other dependency fields. @@ -132,6 +132,7 @@ impl SelectorMapEntry for StateDependency { /// In particular, we want to lookup as few things as possible to get the fewer /// selectors the better, so this looks up by id, class, or looks at the list of /// state/other attribute affecting selectors. +#[derive(Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct InvalidationMap { /// A map from a given class name to all the selectors with that class diff --git a/servo/components/style/invalidation/element/invalidator.rs b/servo/components/style/invalidation/element/invalidator.rs index 055e3e6f3ac8..46b1d53bc1d1 100644 --- a/servo/components/style/invalidation/element/invalidator.rs +++ b/servo/components/style/invalidation/element/invalidator.rs @@ -213,9 +213,9 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> invalidates_self: false, }; - collector.collect_dependencies_in_invalidation_map( - shared_context.stylist.invalidation_map(), - ); + shared_context.stylist.each_invalidation_map(|invalidation_map| { + collector.collect_dependencies_in_invalidation_map(invalidation_map); + }); // TODO(emilio): Consider storing dependencies from the UA sheet in // a different map. If we do that, we can skip the stuff on the @@ -223,9 +223,9 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> // just at that map. let _cut_off_inheritance = self.element.each_xbl_stylist(|stylist| { - collector.collect_dependencies_in_invalidation_map( - stylist.invalidation_map(), - ); + stylist.each_invalidation_map(|invalidation_map| { + collector.collect_dependencies_in_invalidation_map(invalidation_map); + }); }); collector.invalidates_self diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs index b13fd7376cde..3000cd29e278 100644 --- a/servo/components/style/stylist.rs +++ b/servo/components/style/stylist.rs @@ -25,7 +25,7 @@ use rule_tree::{CascadeLevel, RuleTree, StyleSource}; use selector_map::{PrecomputedHashMap, SelectorMap, SelectorMapEntry}; use selector_parser::{SelectorImpl, PerPseudoElementMap, PseudoElement}; use selectors::attr::NamespaceConstraint; -use selectors::bloom::BloomFilter; +use selectors::bloom::{BloomFilter, NonCountingBloomFilter}; use selectors::matching::{ElementSelectorFlags, matches_selector, MatchingContext, MatchingMode}; use selectors::matching::VisitedHandlingMode; use selectors::parser::{AncestorHashes, Combinator, Component, Selector}; @@ -97,9 +97,6 @@ pub struct Stylist { /// The rule tree, that stores the results of selector matching. rule_tree: RuleTree, - /// A map with all the animations indexed by name. - animations: PrecomputedHashMap, - /// Applicable declarations for a given non-eagerly cascaded pseudo-element. /// These are eagerly computed once, and then used to resolve the new /// computed values on the fly on layout. @@ -111,52 +108,6 @@ pub struct Stylist { /// style rule appears in a stylesheet, needed to sort them by source order. rules_source_order: u32, - /// The invalidation map for this document. - invalidation_map: InvalidationMap, - - /// The attribute local names that appear in attribute selectors. Used - /// to avoid taking element snapshots when an irrelevant attribute changes. - /// (We don't bother storing the namespace, since namespaced attributes - /// are rare.) - /// - /// FIXME(heycam): This doesn't really need to be a counting Bloom filter. - #[cfg_attr(feature = "servo", ignore_heap_size_of = "just an array")] - attribute_dependencies: BloomFilter, - - /// Whether `"style"` appears in an attribute selector. This is not common, - /// and by tracking this explicitly, we can avoid taking an element snapshot - /// in the common case of style=""` changing due to modifying - /// `element.style`. (We could track this in `attribute_dependencies`, like - /// all other attributes, but we should probably not risk incorrectly - /// returning `true` for `"style"` just due to a hash collision.) - style_attribute_dependency: bool, - - /// The element state bits that are relied on by selectors. Like - /// `attribute_dependencies`, this is used to avoid taking element snapshots - /// when an irrelevant element state bit changes. - state_dependencies: ElementState, - - /// The ids that appear in the rightmost complex selector of selectors (and - /// hence in our selector maps). Used to determine when sharing styles is - /// safe: we disallow style sharing for elements whose id matches this - /// filter, and hence might be in one of our selector maps. - /// - /// FIXME(bz): This doesn't really need to be a counting Blooom filter. - #[cfg_attr(feature = "servo", ignore_heap_size_of = "just an array")] - mapped_ids: BloomFilter, - - /// Selectors that require explicit cache revalidation (i.e. which depend - /// on state that is not otherwise visible to the cache, like attributes or - /// tree-structural state like child index and pseudos). - #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] - selectors_for_cache_revalidation: SelectorMap, - - /// The total number of selectors. - num_selectors: usize, - - /// The total number of declarations. - num_declarations: usize, - /// The total number of times the stylist has been rebuilt. num_rebuilds: usize, } @@ -239,18 +190,9 @@ impl Stylist { effective_media_query_results: EffectiveMediaQueryResults::new(), cascade_data: CascadeData::new(), - animations: Default::default(), precomputed_pseudo_element_decls: PerPseudoElementMap::default(), rules_source_order: 0, rule_tree: RuleTree::new(), - invalidation_map: InvalidationMap::new(), - attribute_dependencies: BloomFilter::new(), - style_attribute_dependency: false, - state_dependencies: ElementState::empty(), - mapped_ids: BloomFilter::new(), - selectors_for_cache_revalidation: SelectorMap::new(), - num_selectors: 0, - num_declarations: 0, num_rebuilds: 0, } @@ -259,12 +201,12 @@ impl Stylist { /// Returns the number of selectors. pub fn num_selectors(&self) -> usize { - self.num_selectors + self.cascade_data.iter_origins().map(|d| d.num_selectors).sum() } /// Returns the number of declarations. pub fn num_declarations(&self) -> usize { - self.num_declarations + self.cascade_data.iter_origins().map(|d| d.num_declarations).sum() } /// Returns the number of times the stylist has been rebuilt. @@ -274,12 +216,27 @@ impl Stylist { /// Returns the number of revalidation_selectors. pub fn num_revalidation_selectors(&self) -> usize { - self.selectors_for_cache_revalidation.len() + self.cascade_data.iter_origins() + .map(|d| d.selectors_for_cache_revalidation.len()).sum() } - /// Gets a reference to the invalidation map. - pub fn invalidation_map(&self) -> &InvalidationMap { - &self.invalidation_map + /// Returns the number of entries in invalidation maps. + pub fn num_invalidations(&self) -> usize { + self.cascade_data.iter_origins() + .map(|d| d.invalidation_map.len()).sum() + } + + /// Invokes `f` with the `InvalidationMap` for each origin. + /// + /// NOTE(heycam) This might be better as an `iter_invalidation_maps`, once + /// we have `impl trait` and can return that easily without bothering to + /// create a whole new iterator type. + pub fn each_invalidation_map(&self, mut f: F) + where F: FnMut(&InvalidationMap) + { + for origin_cascade_data in self.cascade_data.iter_origins() { + f(&origin_cascade_data.invalidation_map) + } } /// Clear the stylist's state, effectively resetting it to more or less @@ -307,18 +264,9 @@ impl Stylist { self.is_device_dirty = true; // preserve current quirks_mode value self.cascade_data.clear(); - self.animations.clear(); // Or set to Default::default()? self.precomputed_pseudo_element_decls.clear(); self.rules_source_order = 0; // We want to keep rule_tree around across stylist rebuilds. - self.invalidation_map.clear(); - self.attribute_dependencies.clear(); - self.style_attribute_dependency = false; - self.state_dependencies = ElementState::empty(); - self.mapped_ids.clear(); - self.selectors_for_cache_revalidation = SelectorMap::new(); - self.num_selectors = 0; - self.num_declarations = 0; // preserve num_rebuilds value, since it should stay across // clear()/rebuild() cycles. } @@ -459,9 +407,10 @@ impl Stylist { match *rule { CssRule::Style(ref locked) => { let style_rule = locked.read_with(&guard); - self.num_declarations += style_rule.block.read_with(&guard).len(); + origin_cascade_data.num_declarations += + style_rule.block.read_with(&guard).len(); for selector in &style_rule.selectors.0 { - self.num_selectors += 1; + origin_cascade_data.num_selectors += 1; let map = match selector.pseudo_element() { Some(pseudo) if pseudo.is_precomputed() => { @@ -506,20 +455,22 @@ impl Stylist { map.insert(rule, self.quirks_mode); - self.invalidation_map.note_selector(selector, self.quirks_mode); + origin_cascade_data + .invalidation_map + .note_selector(selector, self.quirks_mode); let mut visitor = StylistSelectorVisitor { needs_revalidation: false, passed_rightmost_selector: false, - attribute_dependencies: &mut self.attribute_dependencies, - style_attribute_dependency: &mut self.style_attribute_dependency, - state_dependencies: &mut self.state_dependencies, - mapped_ids: &mut self.mapped_ids, + attribute_dependencies: &mut origin_cascade_data.attribute_dependencies, + style_attribute_dependency: &mut origin_cascade_data.style_attribute_dependency, + state_dependencies: &mut origin_cascade_data.state_dependencies, + mapped_ids: &mut origin_cascade_data.mapped_ids, }; selector.visit(&mut visitor); if visitor.needs_revalidation { - self.selectors_for_cache_revalidation.insert( + origin_cascade_data.selectors_for_cache_revalidation.insert( RevalidationSelectorAndHashes::new(selector.clone(), hashes), self.quirks_mode); } @@ -542,14 +493,15 @@ impl Stylist { debug!("Found valid keyframes rule: {:?}", *keyframes_rule); // Don't let a prefixed keyframes animation override a non-prefixed one. - let needs_insertion = keyframes_rule.vendor_prefix.is_none() || - self.animations.get(keyframes_rule.name.as_atom()).map_or(true, |rule| - rule.vendor_prefix.is_some()); + let needs_insertion = + keyframes_rule.vendor_prefix.is_none() || + origin_cascade_data.animations.get(keyframes_rule.name.as_atom()) + .map_or(true, |rule| rule.vendor_prefix.is_some()); if needs_insertion { let animation = KeyframesAnimation::from_keyframes( &keyframes_rule.keyframes, keyframes_rule.vendor_prefix.clone(), guard); debug!("Found valid keyframe animation: {:?}", animation); - self.animations.insert(keyframes_rule.name.as_atom().clone(), animation); + origin_cascade_data.animations.insert(keyframes_rule.name.as_atom().clone(), animation); } } #[cfg(feature = "gecko")] @@ -576,9 +528,16 @@ impl Stylist { // we rebuild. true } else if *local_name == local_name!("style") { - self.style_attribute_dependency + self.cascade_data + .iter_origins() + .any(|d| d.style_attribute_dependency) } else { - self.attribute_dependencies.might_contain_hash(local_name.get_hash()) + self.cascade_data + .iter_origins() + .any(|d| { + d.attribute_dependencies + .might_contain_hash(local_name.get_hash()) + }) } } @@ -590,14 +549,16 @@ impl Stylist { // rules rely on until we rebuild. true } else { - self.state_dependencies.intersects(state) + self.has_state_dependency(state) } } /// Returns whether the given ElementState bit is relied upon by a selector /// of some rule in the stylist. pub fn has_state_dependency(&self, state: ElementState) -> bool { - self.state_dependencies.intersects(state) + self.cascade_data + .iter_origins() + .any(|d| d.state_dependencies.intersects(state)) } /// Computes the style for a given "precomputed" pseudo-element, taking the @@ -1317,7 +1278,9 @@ impl Stylist { /// of our rule maps. #[inline] pub fn may_have_rules_for_id(&self, id: &Atom) -> bool { - self.mapped_ids.might_contain_hash(id.get_hash()) + self.cascade_data + .iter_origins() + .any(|d| d.mapped_ids.might_contain_hash(id.get_hash())) } /// Return whether the device is dirty, that is, whether the screen size or @@ -1327,10 +1290,13 @@ impl Stylist { self.is_device_dirty } - /// Returns the map of registered `@keyframes` animations. + /// Returns the registered `@keyframes` animation for the specified name. #[inline] - pub fn animations(&self) -> &PrecomputedHashMap { - &self.animations + pub fn get_animation(&self, name: &Atom) -> Option<&KeyframesAnimation> { + self.cascade_data + .iter_origins() + .filter_map(|d| d.animations.get(name)) + .next() } /// Computes the match results of a given element against the set of @@ -1354,17 +1320,19 @@ impl Stylist { // the lookups, which means that the bitvecs are comparable. We verify // this in the caller by asserting that the bitvecs are same-length. let mut results = BitVec::new(); - self.selectors_for_cache_revalidation.lookup( - *element, self.quirks_mode, &mut |selector_and_hashes| { - results.push(matches_selector(&selector_and_hashes.selector, - selector_and_hashes.selector_offset, - Some(&selector_and_hashes.hashes), - element, - &mut matching_context, - flags_setter)); - true - } - ); + for origin_cascade_data in self.cascade_data.iter_origins() { + origin_cascade_data.selectors_for_cache_revalidation.lookup( + *element, self.quirks_mode, &mut |selector_and_hashes| { + results.push(matches_selector(&selector_and_hashes.selector, + selector_and_hashes.selector_offset, + Some(&selector_and_hashes.hashes), + element, + &mut matching_context, + flags_setter)); + true + } + ); + } results } @@ -1470,9 +1438,9 @@ struct StylistSelectorVisitor<'a> { passed_rightmost_selector: bool, /// The filter with all the id's getting referenced from rightmost /// selectors. - mapped_ids: &'a mut BloomFilter, + mapped_ids: &'a mut NonCountingBloomFilter, /// The filter with the local names of attributes there are selectors for. - attribute_dependencies: &'a mut BloomFilter, + attribute_dependencies: &'a mut NonCountingBloomFilter, /// Whether there's any attribute selector for the [style] attribute. style_attribute_dependency: &'a mut bool, /// All the states selectors in the page reference. @@ -1635,6 +1603,11 @@ impl CascadeData { } } +/// Iterator over `PerOriginCascadeData`, from highest level (user) to lowest +/// (user agent). +/// +/// We rely on this specific order for correctly looking up animations +/// (prioritizing rules at higher cascade levels), among other things. struct CascadeDataIter<'a> { cascade_data: &'a CascadeData, cur: usize, @@ -1645,9 +1618,9 @@ impl<'a> Iterator for CascadeDataIter<'a> { fn next(&mut self) -> Option<&'a PerOriginCascadeData> { let result = match self.cur { - 0 => &self.cascade_data.user_agent, + 0 => &self.cascade_data.user, 1 => &self.cascade_data.author, - 2 => &self.cascade_data.user, + 2 => &self.cascade_data.user_agent, _ => return None, }; self.cur += 1; @@ -1666,6 +1639,52 @@ struct PerOriginCascadeData { /// Rules from stylesheets at this `CascadeData`'s origin that correspond /// to a given pseudo-element. pseudos_map: PerPseudoElementMap>, + + /// A map with all the animations at this `CascadeData`'s origin, indexed + /// by name. + animations: PrecomputedHashMap, + + /// The invalidation map for the rules at this origin. + invalidation_map: InvalidationMap, + + /// The attribute local names that appear in attribute selectors. Used + /// to avoid taking element snapshots when an irrelevant attribute changes. + /// (We don't bother storing the namespace, since namespaced attributes + /// are rare.) + #[cfg_attr(feature = "servo", ignore_heap_size_of = "just an array")] + attribute_dependencies: NonCountingBloomFilter, + + /// Whether `"style"` appears in an attribute selector. This is not common, + /// and by tracking this explicitly, we can avoid taking an element snapshot + /// in the common case of style=""` changing due to modifying + /// `element.style`. (We could track this in `attribute_dependencies`, like + /// all other attributes, but we should probably not risk incorrectly + /// returning `true` for `"style"` just due to a hash collision.) + style_attribute_dependency: bool, + + /// The element state bits that are relied on by selectors. Like + /// `attribute_dependencies`, this is used to avoid taking element snapshots + /// when an irrelevant element state bit changes. + state_dependencies: ElementState, + + /// The ids that appear in the rightmost complex selector of selectors (and + /// hence in our selector maps). Used to determine when sharing styles is + /// safe: we disallow style sharing for elements whose id matches this + /// filter, and hence might be in one of our selector maps. + #[cfg_attr(feature = "servo", ignore_heap_size_of = "just an array")] + mapped_ids: NonCountingBloomFilter, + + /// Selectors that require explicit cache revalidation (i.e. which depend + /// on state that is not otherwise visible to the cache, like attributes or + /// tree-structural state like child index and pseudos). + #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] + selectors_for_cache_revalidation: SelectorMap, + + /// The total number of selectors. + num_selectors: usize, + + /// The total number of declarations. + num_declarations: usize, } impl PerOriginCascadeData { @@ -1673,6 +1692,15 @@ impl PerOriginCascadeData { Self { element_map: SelectorMap::new(), pseudos_map: PerPseudoElementMap::default(), + animations: Default::default(), + invalidation_map: InvalidationMap::new(), + attribute_dependencies: NonCountingBloomFilter::new(), + style_attribute_dependency: false, + state_dependencies: ElementState::empty(), + mapped_ids: NonCountingBloomFilter::new(), + selectors_for_cache_revalidation: SelectorMap::new(), + num_selectors: 0, + num_declarations: 0, } } @@ -1685,7 +1713,17 @@ impl PerOriginCascadeData { } fn clear(&mut self) { - *self = Self::new(); + self.element_map = SelectorMap::new(); + self.pseudos_map = Default::default(); + self.animations = Default::default(); + self.invalidation_map.clear(); + self.attribute_dependencies.clear(); + self.style_attribute_dependency = false; + self.state_dependencies = ElementState::empty(); + self.mapped_ids.clear(); + self.selectors_for_cache_revalidation = SelectorMap::new(); + self.num_selectors = 0; + self.num_declarations = 0; } fn has_rules_for_pseudo(&self, pseudo: &PseudoElement) -> bool { @@ -1761,8 +1799,8 @@ impl Rule { /// A function to be able to test the revalidation stuff. pub fn needs_revalidation_for_testing(s: &Selector) -> bool { - let mut attribute_dependencies = BloomFilter::new(); - let mut mapped_ids = BloomFilter::new(); + let mut attribute_dependencies = NonCountingBloomFilter::new(); + let mut mapped_ids = NonCountingBloomFilter::new(); let mut style_attribute_dependency = false; let mut state_dependencies = ElementState::empty(); let mut visitor = StylistSelectorVisitor { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 0f66aefe6df7..ae656c6022c3 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -3297,7 +3297,7 @@ pub extern "C" fn Servo_StyleSet_GetKeyframesForName(raw_data: RawServoStyleSetB let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) }; - let animation = match data.stylist.animations().get(&name) { + let animation = match data.stylist.get_animation(&name) { Some(animation) => animation, None => return false, }; From 917c4fb30f74ace1a3f02bdbc2f97d2f74b579fb Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Sun, 6 Aug 2017 14:08:29 -0400 Subject: [PATCH 118/166] Bug 1387831 - mochitest clipboard isn't running on windows anymore. r=jmaher,kmoir We accidentally left mochitest clipboard enabled only for try, this removes its tier setting of 2 on windows 7, and makes it run wherever the corresponding builds run. MozReview-Commit-ID: I2ybhqPtswV --HG-- extra : rebase_source : 2516f6bce22e66a3444ac8c61231a47a74de3c0c --- taskcluster/ci/test/tests.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/taskcluster/ci/test/tests.yml b/taskcluster/ci/test/tests.yml index d2ef94b7a565..478eeb7501e4 100644 --- a/taskcluster/ci/test/tests.yml +++ b/taskcluster/ci/test/tests.yml @@ -695,10 +695,6 @@ mochitest-clipboard: loopback-video: true virtualization: hardware instance-size: xlarge - run-on-projects: - by-test-platform: - windows.*: ['try'] - default: built-projects worker-type: by-test-platform: windows7-32.*: buildbot-bridge/buildbot-bridge @@ -732,10 +728,6 @@ mochitest-clipboard: - remove_executables.py extra-options: - --mochitest-suite=plain-clipboard,chrome-clipboard,browser-chrome-clipboard - tier: - by-test-platform: - windows7-32.*: 2 - default: default mochitest-devtools-chrome: description: "Mochitest devtools-chrome run" From 6e5bf84c9f800ed4f27af3045c2b5ff182cc27e1 Mon Sep 17 00:00:00 2001 From: Dennis Schubert Date: Fri, 4 Aug 2017 14:30:25 +0200 Subject: [PATCH 119/166] Bug 1376602 - Part 1: Import sources for WebCompat Go Faster 1.2. r=Felipe MozReview-Commit-ID: cLuF81S7H4 --HG-- extra : rebase_source : 3a92adf155da360e42c8fddc59d131907124b7df --- browser/extensions/webcompat/bootstrap.js | 30 +++++++++++++------ .../webcompat/content/lib/ua_overrider.jsm | 26 +++++----------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/browser/extensions/webcompat/bootstrap.js b/browser/extensions/webcompat/bootstrap.js index 05134f849089..6b39ad6b6491 100644 --- a/browser/extensions/webcompat/bootstrap.js +++ b/browser/extensions/webcompat/bootstrap.js @@ -2,12 +2,15 @@ * 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/. */ -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); +const {utils: Cu} = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); const PREF_BRANCH = "extensions.webcompat."; const PREF_DEFAULTS = {perform_ua_overrides: true}; +const UA_OVERRIDES_INIT_TOPIC = "useragentoverrides-initialized"; const UA_ENABLE_PREF_NAME = "extensions.webcompat.perform_ua_overrides"; XPCOMUtils.defineLazyModuleGetter(this, "UAOverrider", "chrome://webcompat/content/lib/ua_overrider.jsm"); @@ -21,7 +24,6 @@ function UAEnablePrefObserver() { overrider = new UAOverrider(UAOverrides); overrider.init(); } else if (!isEnabled && overrider) { - overrider.uninit(); overrider = null; } } @@ -60,14 +62,24 @@ this.startup = function({webExtension}) { Services.prefs.clearUserPref(UA_ENABLE_PREF_NAME); Services.prefs.addObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver); - overrider = new UAOverrider(UAOverrides); - overrider.init(); + // Listen to the useragentoverrides-initialized notification we get and + // initialize our overrider there. This is done to avoid slowing down the + // apparent startup proces, since we avoid loading anything before the first + // window is visible to the user. See bug 1371442 for details. + let startupWatcher = { + observe(aSubject, aTopic, aData) { + if (aTopic !== UA_OVERRIDES_INIT_TOPIC) { + return; + } + + Services.obs.removeObserver(this, UA_OVERRIDES_INIT_TOPIC); + overrider = new UAOverrider(UAOverrides); + overrider.init(); + } + }; + Services.obs.addObserver(startupWatcher, UA_OVERRIDES_INIT_TOPIC); }; this.shutdown = function() { Services.prefs.removeObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver); - - if (overrider) { - overrider.uninit(); - } }; diff --git a/browser/extensions/webcompat/content/lib/ua_overrider.jsm b/browser/extensions/webcompat/content/lib/ua_overrider.jsm index 556601b91f26..7a1f4e7bb2c6 100644 --- a/browser/extensions/webcompat/content/lib/ua_overrider.jsm +++ b/browser/extensions/webcompat/content/lib/ua_overrider.jsm @@ -7,10 +7,8 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Console.jsm"); -const DefaultUA = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent; -const NS_HTTP_ON_USERAGENT_REQUEST_TOPIC = "http-on-useragent-request"; - XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "eTLDService", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"); class UAOverrider { @@ -35,24 +33,14 @@ class UAOverrider { } init() { - Services.obs.addObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC); + UserAgentOverrides.addComplexOverride(this.overrideCallback.bind(this)); } - uninit() { - Services.obs.removeObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC); - } - - observe(subject, topic) { - if (topic !== NS_HTTP_ON_USERAGENT_REQUEST_TOPIC) { - return; - } - - let channel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); - let uaOverride = this.lookupUAOverride(channel.URI); - + overrideCallback(channel, defaultUA) { + let uaOverride = this.lookupUAOverride(channel.URI, defaultUA); if (uaOverride) { console.log("The user agent has been overridden for compatibility reasons."); - channel.setRequestHeader("User-Agent", uaOverride, false); + return uaOverride; } } @@ -88,12 +76,12 @@ class UAOverrider { * If there are more than one possible overrides, that is if two or more * uriMatchers would return true, the first one gets applied. */ - lookupUAOverride(uri) { + lookupUAOverride(uri, defaultUA) { let baseDomain = this.getBaseDomainFromURI(uri); if (baseDomain && this._overrides[baseDomain]) { for (let uaOverride of this._overrides[baseDomain]) { if (uaOverride.uriMatcher(uri.specIgnoringRef)) { - return uaOverride.uaTransformer(DefaultUA); + return uaOverride.uaTransformer(defaultUA); } } } From 767bd4d5532b19ef58524987a9ab2487d9696d39 Mon Sep 17 00:00:00 2001 From: Dennis Schubert Date: Fri, 4 Aug 2017 14:34:14 +0200 Subject: [PATCH 120/166] Bug 1376602 - Part 2: Add WebCompat Go Faster modules to browser_startup tests. r=Felipe MozReview-Commit-ID: Ic1tpivC7Na --HG-- extra : rebase_source : 87260a9aff8e6f2e6c323d67e9bf959e917cf892 --- browser/base/content/test/performance/browser_startup.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/base/content/test/performance/browser_startup.js b/browser/base/content/test/performance/browser_startup.js index 100224ac30a5..203aa8e472b4 100644 --- a/browser/base/content/test/performance/browser_startup.js +++ b/browser/base/content/test/performance/browser_startup.js @@ -66,6 +66,8 @@ const startupPhases = { modules: new Set([ "chrome://webcompat-reporter/content/TabListener.jsm", "chrome://webcompat-reporter/content/WebCompatReporter.jsm", + "chrome://webcompat/content/data/ua_overrides.jsm", + "chrome://webcompat/content/lib/ua_overrider.jsm", "resource:///modules/AboutNewTab.jsm", "resource:///modules/BrowserUITelemetry.jsm", "resource:///modules/BrowserUsageTelemetry.jsm", From 58e5987209f6f86a140a9238e80a5f3af1b21f91 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 9 Aug 2017 08:31:26 +1000 Subject: [PATCH 121/166] Bug 1383992 part 1 - Disable failing mochitests. r=heycam MozReview-Commit-ID: J9LoovJJJgM --HG-- extra : rebase_source : a5ed4b2a11c293c50d642c3a0da6831ce5a885a1 extra : source : 8d97565b7dedaef3b46e65b92b1ca1e0598d2a76 extra : histedit_source : 72834d0bc485e78cb8c1de357e4b545d7e6408f5 --- devtools/server/tests/mochitest/chrome.ini | 1 + dom/base/test/mochitest.ini | 3 +++ dom/html/test/test_fullscreen-api.html | 9 +++++++++ image/test/mochitest/test_xultree_animation.xhtml | 5 +++++ layout/base/tests/mochitest.ini | 2 ++ layout/inspector/tests/mochitest.ini | 4 ++++ layout/style/test/browser.ini | 1 + layout/style/test/mochitest.ini | 3 +++ layout/xul/test/test_bug381167.xhtml | 5 +++++ 9 files changed, 33 insertions(+) diff --git a/devtools/server/tests/mochitest/chrome.ini b/devtools/server/tests/mochitest/chrome.ini index 26899b65a87d..df062c9ffdd6 100644 --- a/devtools/server/tests/mochitest/chrome.ini +++ b/devtools/server/tests/mochitest/chrome.ini @@ -34,6 +34,7 @@ support-files = [test_css-logic.html] [test_css-logic-media-queries.html] [test_css-logic-specificity.html] +fail-if = stylo # bug 1387905 [test_css-properties.html] [test_Debugger.Source.prototype.introductionScript.html] [test_Debugger.Source.prototype.introductionType.html] diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index fe2651690f44..656e6f84eb34 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -313,6 +313,7 @@ skip-if = toolkit == 'android' [test_bug338583.html] skip-if = toolkit == 'android' [test_bug338679.html] +fail-if = stylo # bug 1370779 [test_bug339494.html] [test_bug339494.xhtml] [test_bug340571.html] @@ -680,6 +681,7 @@ skip-if = (toolkit == 'android') # Android: Bug 775227 [test_innersize_scrollport.html] [test_integer_attr_with_leading_zero.html] [test_intersectionobservers.html] +skip-if = stylo # timeout bug 1384001 [test_link_prefetch.html] skip-if = !e10s # Track Bug 1281415 [test_link_stylesheet.html] @@ -703,6 +705,7 @@ skip-if = (os != 'android') # meta-viewport tag support is mobile-only [test_mozbrowser_apis_blocked.html] [test_mozMatchesSelector.html] [test_mutationobserver_anonymous.html] +skip-if = stylo # bug 1383985 [test_mutationobservers.html] [test_named_frames.html] [test_navigator_hardwareConcurrency.html] diff --git a/dom/html/test/test_fullscreen-api.html b/dom/html/test/test_fullscreen-api.html index 2564ea8f8c1b..e21f91def704 100644 --- a/dom/html/test/test_fullscreen-api.html +++ b/dom/html/test/test_fullscreen-api.html @@ -77,6 +77,15 @@ function shouldSkipTest(test) { } } } + if (SpecialPowers.DOMWindowUtils.isStyledByServo && + SpecialPowers.isDebugBuild && + navigator.platform.indexOf('Mac') >= 0) { + if (test == "file_fullscreen-backdrop.html") { + todo(false, `${test} skipped due to bug 1387942`); + return true; + } + } + return false; } diff --git a/image/test/mochitest/test_xultree_animation.xhtml b/image/test/mochitest/test_xultree_animation.xhtml index d37f6252eed6..78658d3dd780 100644 --- a/image/test/mochitest/test_xultree_animation.xhtml +++ b/image/test/mochitest/test_xultree_animation.xhtml @@ -50,6 +50,11 @@ Mozilla Bug 666446: lots of animated gifs swamp us with paint events /** Test for Bug 666446 nsSVGFEImageElement/RasterImage**/ +if (SpecialPowers.DOMWindowUtils.isStyledByServo) { + // Stylo currently asserts for any XUL bits. + SimpleTest.expectAssertions(9, 9); +} + const FAILURE_TIMEOUT = 5000; // Fail early after 120 seconds (2 minutes) function main() { diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 15aad7db1485..185bcb73fa8d 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -77,6 +77,7 @@ support-files = bug687297_a.html bug687297_b.html bug687297_c.html +fail-if = stylo # bug 1375332 [test_bug696020.html] [test_bug718809.html] [test_bug725426.html] @@ -135,6 +136,7 @@ support-files = bug1226904.html [test_bug1246622.html] [test_bug1278021.html] [test_emulateMedium.html] +fail-if = stylo # bug 1371395 [test_event_target_iframe_oop.html] skip-if = e10s # bug 1020135, nested oop iframes not supported support-files = bug921928_event_target_iframe_apps_oop.html diff --git a/layout/inspector/tests/mochitest.ini b/layout/inspector/tests/mochitest.ini index b99650fef7ae..e3db49d8a5d1 100644 --- a/layout/inspector/tests/mochitest.ini +++ b/layout/inspector/tests/mochitest.ini @@ -9,6 +9,7 @@ support-files = [test_bug462789.html] [test_bug522601.xhtml] [test_bug536379.html] +fail-if = stylo # bug 1387913 [test_bug536379-2.html] [test_bug557726.html] [test_bug609549.xhtml] @@ -27,9 +28,12 @@ support-files = getCSSStyleRules-2.css [test_getCSSPseudoElementNames.html] [test_getRelativeRuleLine.html] +fail-if = stylo # bug 1387932 [test_get_all_style_sheets.html] [test_is_valid_css_color.html] [test_isinheritableproperty.html] [test_parseStyleSheet.html] [test_parseStyleSheetImport.html] +fail-if = stylo # bug 1387933 [test_selectormatcheselement.html] +fail-if = stylo # bug 1387934 diff --git a/layout/style/test/browser.ini b/layout/style/test/browser.ini index 1777127c08e8..b48bc89b241f 100644 --- a/layout/style/test/browser.ini +++ b/layout/style/test/browser.ini @@ -11,4 +11,5 @@ support-files = [browser_bug453896.js] [browser_newtab_share_rule_processors.js] +skip-if = stylo # Gecko-specific test [browser_sourcemap.js] diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index c6cbb1b6b48e..b165615a760c 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -239,6 +239,7 @@ skip-if = !stylo skip-if = android_version == '18' #debug-only failure; timed out #Android 4.3 aws only; bug 1030419 [test_media_queries_dynamic.html] [test_media_queries_dynamic_xbl.html] +fail-if = stylo # bug 1382078 [test_media_query_list.html] [test_moz_device_pixel_ratio.html] [test_namespace_rule.html] @@ -265,6 +266,7 @@ support-files = redundant_font_download.sjs [test_restyle_table_wrapper.html] [test_restyles_in_smil_animation.html] skip-if = toolkit == 'android' # bug 1328522 +fail-if = stylo # bug 1387935 [test_root_node_display.html] [test_rule_insertion.html] [test_rule_serialization.html] @@ -272,6 +274,7 @@ skip-if = toolkit == 'android' # bug 1328522 [test_selectors.html] skip-if = toolkit == 'android' #bug 775227 [test_selectors_on_anonymous_content.html] +fail-if = stylo # bug 1382102 [test_setPropertyWithNull.html] [test_shorthand_property_getters.html] [test_specified_value_serialization.html] diff --git a/layout/xul/test/test_bug381167.xhtml b/layout/xul/test/test_bug381167.xhtml index 3f98d7a4d68f..b0af492db299 100644 --- a/layout/xul/test/test_bug381167.xhtml +++ b/layout/xul/test/test_bug381167.xhtml @@ -26,6 +26,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=381167 SimpleTest.waitForExplicitFinish(); +if (SpecialPowers.DOMWindowUtils.isStyledByServo) { + // Stylo currently asserts for any XUL bits. + SimpleTest.expectAssertions(5, 5); +} + function closeit() { var evt = document.createEvent('KeyboardEvent'); evt.initKeyEvent('keypress', true, true, From a7579e7241ad2092826e28a3e5fd171addaf437b Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 9 Aug 2017 08:31:26 +1000 Subject: [PATCH 122/166] Bug 1383992 part 2 - Enable some more mochitests for stylo. r=jmaher MozReview-Commit-ID: AnZAxhPwwEB --HG-- extra : rebase_source : 89418b819a53f1d1e5a5cd2861f31af1ff901844 extra : source : 1bc1f2000c0a4e9e23f5e2f05b7d95e44c615238 extra : histedit_source : ad7d9650d49c698d03d6397aa1ad27e860ae7827 --- layout/style/test/moz.build | 11 --- layout/style/test/stylo-failures.md | 51 ----------- taskcluster/ci/test/test-sets.yml | 11 ++- taskcluster/ci/test/tests.yml | 84 +++++++------------ .../configs/unittests/linux_unittest.py | 2 - .../configs/unittests/mac_unittest.py | 2 - .../unittests/win_taskcluster_unittest.py | 2 - 7 files changed, 40 insertions(+), 123 deletions(-) delete mode 100644 layout/style/test/stylo-failures.md diff --git a/layout/style/test/moz.build b/layout/style/test/moz.build index 3f160b4cd5dc..fa646ca16dd3 100644 --- a/layout/style/test/moz.build +++ b/layout/style/test/moz.build @@ -123,17 +123,6 @@ TEST_HARNESS_FILES.testing.mochitest.tests.layout.style.test['css-visited'] += [ '/layout/reftests/svg/pseudo-classes-02.svg', ] -if CONFIG['MOZ_STYLO']: - TEST_HARNESS_FILES.testing.mochitest.tests.layout.style.test += [ - 'stylo-failures.md', - ] - TEST_HARNESS_FILES.testing.mochitest.chrome.layout.style.test += [ - 'stylo-failures.md', - ] - # TEST_HARNESS_FILES.testing.mochitest.browser.layout.style.test += [ - # 'stylo-failures.md', - # ] - DEFINES['MOZILLA_INTERNAL_API'] = True if CONFIG['MOZ_ENABLE_MASK_AS_SHORTHAND']: HOST_DEFINES['MOZ_ENABLE_MASK_AS_SHORTHAND'] = True diff --git a/layout/style/test/stylo-failures.md b/layout/style/test/stylo-failures.md deleted file mode 100644 index a6d1a3d5dbf7..000000000000 --- a/layout/style/test/stylo-failures.md +++ /dev/null @@ -1,51 +0,0 @@ -This file describes test failures we currently have for stylo. - -Failure patterns are described in the following format: -* test_name.html [number] -* test_name.html `pattern` [number] -* test_name.html: description [number] -* test_name.html `pattern`: description [number] -* test_name.html asserts [number] -* test_name.html asserts: description [number] - -In which -* test_name.html is the name of the test. It could be "..." which means - the same name as the previous failure pattern. -* description is a comment for the supposed reason of the failure. -* [number] is the expected count of the failure, which can be a "*" meaning - any positive number. -* `pattern` is a substring of the failure message. If there are multiple items - for the same test file, a failure is captured by the first matched pattern. - For example, if there is a failure with message "foo bar", and there is a - pattern `foo` followed by a pattern `bar`, this failure would be counted in - the pattern `foo`. -* "asserts" means it is for assertion. Number of assertions of a same test is - accumulated, unlike `pattern`. And number of assertions cannot be "*". - -Any line which doesn't follow the format above would be ignored like comment. - -To use this file, you need to add `--failure-pattern-file=stylo-failures.md` -to mochitest command. - -## Failures - -* Media query support: - * test_media_queries_dynamic_xbl.html: xbl support bug 1382078 [1] -* Animation support: - * SMIL Animation - * test_restyles_in_smil_animation.html [2] -* Incorrect serialization - * place-{content,items,self} shorthands bug 1363971 - * test_align_shorthand_serialization.html [6] -* Unit should be preserved after parsing servo/servo#15346 -* test_author_specified_style.html: support serializing color as author specified bug 1348165 [27] -* browser_newtab_share_rule_processors.js: agent style sheet sharing [1] -* test_selectors_on_anonymous_content.html: xbl and :nth-child bug 1382102 [1] - -## Assertions - -## Need Gecko change - -## Unknown / Unsure - -## Ignore diff --git a/taskcluster/ci/test/test-sets.yml b/taskcluster/ci/test/test-sets.yml index b182d132ceff..43cc7845e54d 100644 --- a/taskcluster/ci/test/test-sets.yml +++ b/taskcluster/ci/test/test-sets.yml @@ -84,15 +84,20 @@ stylo-tests: - crashtest - reftest - reftest-stylo - - mochitest-style - - mochitest-chrome-style - web-platform-tests - web-platform-tests-reftests + - mochitest + - mochitest-browser-screenshots + - mochitest-chrome + - mochitest-clipboard + - mochitest-gpu + - mochitest-media + - mochitest-webgl stylo-sequential-tests: - crashtest - reftest-stylo - - mochitest-style + - mochitest qr-tests: - cppunit diff --git a/taskcluster/ci/test/tests.yml b/taskcluster/ci/test/tests.yml index 478eeb7501e4..e702b420db50 100644 --- a/taskcluster/ci/test/tests.yml +++ b/taskcluster/ci/test/tests.yml @@ -445,7 +445,14 @@ mochitest: allow-software-gl-layers: false run-on-projects: by-test-platform: + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] + windows7-32-stylo.*: ['autoland', 'mozilla-central', 'try'] default: built-projects + tier: + by-test-platform: + macosx64-stylo/.*: 2 + default: default mozharness: by-test-platform: android.*: @@ -620,6 +627,9 @@ mochitest-chrome: run-on-projects: by-test-platform: windows7-32.*: ['try'] + linux64-stylo/debug: ['try'] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] default: built-projects worker-type: by-test-platform: @@ -660,34 +670,10 @@ mochitest-chrome: tier: by-test-platform: windows7-32.*: 2 + macosx64-stylo/.*: 2 + linux64-stylo/debug: 3 default: default -mochitest-chrome-style: - description: "Mochitest chrome run for style system" - suite: mochitest/chrome-style - treeherder-symbol: tc-M(cs) - loopback-video: true - run-on-projects: - by-test-platform: - .*-stylo.*: ['autoland', 'mozilla-central', 'try'] - default: built-projects - e10s: false - mozharness: - mochitest-flavor: chrome - script: desktop_unittest.py - no-read-buildbot-config: true - config: - by-test-platform: - windows.*: - - unittests/win_taskcluster_unittest.py - macosx.*: - - unittests/mac_unittest.py - default: - - unittests/linux_unittest.py - - remove_executables.py - extra-options: - - --mochitest-suite=chrome-style - mochitest-clipboard: description: "Mochitest clipboard run" suite: mochitest/clipboard @@ -695,6 +681,9 @@ mochitest-clipboard: loopback-video: true virtualization: hardware instance-size: xlarge + linux64-stylo/debug: ['try'] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] worker-type: by-test-platform: windows7-32.*: buildbot-bridge/buildbot-bridge @@ -728,6 +717,8 @@ mochitest-clipboard: - remove_executables.py extra-options: - --mochitest-suite=plain-clipboard,chrome-clipboard,browser-chrome-clipboard + macosx64-stylo/.*: 2 + linux64-stylo/debug: 3 mochitest-devtools-chrome: description: "Mochitest devtools-chrome run" @@ -749,7 +740,9 @@ mochitest-devtools-chrome: windows8-64.*: ['mozilla-release', 'mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland'] windows8-64-devedition/opt: built-projects # No dev edition outside of supported branches windows10.*: [] - .*-stylo.*: ['autoland', 'mozilla-central', 'try'] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] + windows7-32-stylo.*: ['autoland', 'mozilla-central', 'try'] default: built-projects worker-type: by-test-platform: @@ -799,6 +792,9 @@ mochitest-gpu: windows8-64.*: ['mozilla-release', 'mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland'] windows8-64-devedition/opt: built-projects # No dev edition outside of supported branches windows10.*: [] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] + windows7-32-stylo.*: ['autoland', 'mozilla-central', 'try'] default: built-projects worker-type: by-test-platform: @@ -834,6 +830,7 @@ mochitest-gpu: tier: by-test-platform: linux64-qr/.*: 1 + macosx64-stylo/.*: 2 default: default mochitest-jetpack: @@ -883,6 +880,9 @@ mochitest-media: windows8-64.*: ['mozilla-release', 'mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland'] windows8-64-devedition/opt: built-projects # No dev edition outside of supported branches windows10.*: [] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] + windows7-32-stylo.*: ['autoland', 'mozilla-central', 'try'] default: built-projects worker-type: by-test-platform: @@ -921,33 +921,9 @@ mochitest-media: tier: by-test-platform: linux64-qr/.*: 1 + macosx64-stylo/.*: 2 default: default -mochitest-style: - description: "Mochitest plain run for style system" - suite: mochitest/plain-style - treeherder-symbol: tc-M(s) - loopback-video: true - run-on-projects: - by-test-platform: - .*-stylo.*: ['autoland', 'mozilla-central', 'try'] - default: built-projects - mozharness: - mochitest-flavor: plain - script: desktop_unittest.py - no-read-buildbot-config: true - config: - by-test-platform: - windows.*: - - unittests/win_taskcluster_unittest.py - macosx.*: - - unittests/mac_unittest.py - default: - - unittests/linux_unittest.py - - remove_executables.py - extra-options: - - --mochitest-suite=plain-style - mochitest-valgrind: description: "Mochitest plain Valgrind run" suite: mochitest/valgrind-plain @@ -988,6 +964,9 @@ mochitest-webgl: windows8-64.*: ['mozilla-release', 'mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland'] windows8-64-devedition/opt: built-projects # No dev edition outside of supported branches windows10.*: [] + linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] + macosx64-stylo/.*: ['mozilla-central', 'try'] + windows7-32-stylo.*: ['autoland', 'mozilla-central', 'try'] default: built-projects worker-type: by-test-platform: @@ -1038,6 +1017,7 @@ mochitest-webgl: tier: by-test-platform: linux64-qr/.*: 1 + macosx64-stylo/.*: 2 default: default reftest: diff --git a/testing/mozharness/configs/unittests/linux_unittest.py b/testing/mozharness/configs/unittests/linux_unittest.py index eeee3d279d60..ecc5c884fb68 100644 --- a/testing/mozharness/configs/unittests/linux_unittest.py +++ b/testing/mozharness/configs/unittests/linux_unittest.py @@ -207,8 +207,6 @@ config = { "jetpack-package-clipboard": ["--flavor=jetpack-package", "--subsuite=clipboard"], "jetpack-addon": ["--flavor=jetpack-addon"], "a11y": ["--flavor=a11y"], - "plain-style": ["--failure-pattern-file=stylo-failures.md", "layout/style/test", "dom/smil/test", "dom/animation/test"], - "chrome-style": ["--flavor=chrome", "--failure-pattern-file=../stylo-failures.md", "layout/style/test/chrome", "dom/animation/test"], }, # local reftest suites "all_reftest_suites": { diff --git a/testing/mozharness/configs/unittests/mac_unittest.py b/testing/mozharness/configs/unittests/mac_unittest.py index 1b3bcbaf10a4..2b45baac3ef7 100644 --- a/testing/mozharness/configs/unittests/mac_unittest.py +++ b/testing/mozharness/configs/unittests/mac_unittest.py @@ -170,8 +170,6 @@ config = { "jetpack-package-clipboard": ["--flavor=jetpack-package", "--subsuite=clipboard"], "jetpack-addon": ["--flavor=jetpack-addon"], "a11y": ["--flavor=a11y"], - "plain-style": ["--failure-pattern-file=stylo-failures.md", "layout/style/test", "dom/smil/test", "dom/animation/test"], - "chrome-style": ["--flavor=chrome", "--failure-pattern-file=../stylo-failures.md", "layout/style/test/chrome", "dom/animation/test"], }, # local reftest suites "all_reftest_suites": { diff --git a/testing/mozharness/configs/unittests/win_taskcluster_unittest.py b/testing/mozharness/configs/unittests/win_taskcluster_unittest.py index e123d08db49e..2eb6b78d6d04 100644 --- a/testing/mozharness/configs/unittests/win_taskcluster_unittest.py +++ b/testing/mozharness/configs/unittests/win_taskcluster_unittest.py @@ -182,8 +182,6 @@ config = { "jetpack-package-clipboard": ["--flavor=jetpack-package", "--subsuite=clipboard"], "jetpack-addon": ["--flavor=jetpack-addon"], "a11y": ["--flavor=a11y"], - "plain-style": ["--failure-pattern-file=stylo-failures.md", "layout/style/test", "dom/smil/test", "dom/animation/test"], - "chrome-style": ["--flavor=chrome", "--failure-pattern-file=../stylo-failures.md", "layout/style/test/chrome", "dom/animation/test"], }, # local reftest suites "all_reftest_suites": { From 0a7d0bffe6674497a44b92b313f7c3cea779fb0c Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 10 Aug 2017 12:07:17 +1000 Subject: [PATCH 123/166] Bug 1383992 followup - Fix tests.yml. MozReview-Commit-ID: 5ySe3J9QBCT --- taskcluster/ci/test/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/taskcluster/ci/test/tests.yml b/taskcluster/ci/test/tests.yml index e702b420db50..b8e952c8c55e 100644 --- a/taskcluster/ci/test/tests.yml +++ b/taskcluster/ci/test/tests.yml @@ -681,9 +681,12 @@ mochitest-clipboard: loopback-video: true virtualization: hardware instance-size: xlarge + run-on-projects: + by-test-platform: linux64-stylo/debug: ['try'] linux64-stylo.*: ['autoland', 'mozilla-central', 'try'] macosx64-stylo/.*: ['mozilla-central', 'try'] + default: built-projects worker-type: by-test-platform: windows7-32.*: buildbot-bridge/buildbot-bridge @@ -717,8 +720,11 @@ mochitest-clipboard: - remove_executables.py extra-options: - --mochitest-suite=plain-clipboard,chrome-clipboard,browser-chrome-clipboard + tier: + by-test-platform: macosx64-stylo/.*: 2 linux64-stylo/debug: 3 + default: default mochitest-devtools-chrome: description: "Mochitest devtools-chrome run" From 291167d9ca30520cea98d6404997fc1499abeecf Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 9 Aug 2017 22:33:52 -0400 Subject: [PATCH 124/166] Backed out changesets c95150c0fe9d and 9c1e1102bbc3 (bug 1376602) for ESLint failures. --- .../test/performance/browser_startup.js | 2 -- browser/extensions/webcompat/bootstrap.js | 30 ++++++------------- .../webcompat/content/lib/ua_overrider.jsm | 26 +++++++++++----- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/browser/base/content/test/performance/browser_startup.js b/browser/base/content/test/performance/browser_startup.js index 203aa8e472b4..100224ac30a5 100644 --- a/browser/base/content/test/performance/browser_startup.js +++ b/browser/base/content/test/performance/browser_startup.js @@ -66,8 +66,6 @@ const startupPhases = { modules: new Set([ "chrome://webcompat-reporter/content/TabListener.jsm", "chrome://webcompat-reporter/content/WebCompatReporter.jsm", - "chrome://webcompat/content/data/ua_overrides.jsm", - "chrome://webcompat/content/lib/ua_overrider.jsm", "resource:///modules/AboutNewTab.jsm", "resource:///modules/BrowserUITelemetry.jsm", "resource:///modules/BrowserUsageTelemetry.jsm", diff --git a/browser/extensions/webcompat/bootstrap.js b/browser/extensions/webcompat/bootstrap.js index 6b39ad6b6491..05134f849089 100644 --- a/browser/extensions/webcompat/bootstrap.js +++ b/browser/extensions/webcompat/bootstrap.js @@ -2,15 +2,12 @@ * 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/. */ -const {utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); const PREF_BRANCH = "extensions.webcompat."; const PREF_DEFAULTS = {perform_ua_overrides: true}; -const UA_OVERRIDES_INIT_TOPIC = "useragentoverrides-initialized"; const UA_ENABLE_PREF_NAME = "extensions.webcompat.perform_ua_overrides"; XPCOMUtils.defineLazyModuleGetter(this, "UAOverrider", "chrome://webcompat/content/lib/ua_overrider.jsm"); @@ -24,6 +21,7 @@ function UAEnablePrefObserver() { overrider = new UAOverrider(UAOverrides); overrider.init(); } else if (!isEnabled && overrider) { + overrider.uninit(); overrider = null; } } @@ -62,24 +60,14 @@ this.startup = function({webExtension}) { Services.prefs.clearUserPref(UA_ENABLE_PREF_NAME); Services.prefs.addObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver); - // Listen to the useragentoverrides-initialized notification we get and - // initialize our overrider there. This is done to avoid slowing down the - // apparent startup proces, since we avoid loading anything before the first - // window is visible to the user. See bug 1371442 for details. - let startupWatcher = { - observe(aSubject, aTopic, aData) { - if (aTopic !== UA_OVERRIDES_INIT_TOPIC) { - return; - } - - Services.obs.removeObserver(this, UA_OVERRIDES_INIT_TOPIC); - overrider = new UAOverrider(UAOverrides); - overrider.init(); - } - }; - Services.obs.addObserver(startupWatcher, UA_OVERRIDES_INIT_TOPIC); + overrider = new UAOverrider(UAOverrides); + overrider.init(); }; this.shutdown = function() { Services.prefs.removeObserver(UA_ENABLE_PREF_NAME, UAEnablePrefObserver); + + if (overrider) { + overrider.uninit(); + } }; diff --git a/browser/extensions/webcompat/content/lib/ua_overrider.jsm b/browser/extensions/webcompat/content/lib/ua_overrider.jsm index 7a1f4e7bb2c6..556601b91f26 100644 --- a/browser/extensions/webcompat/content/lib/ua_overrider.jsm +++ b/browser/extensions/webcompat/content/lib/ua_overrider.jsm @@ -7,8 +7,10 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Console.jsm"); +const DefaultUA = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent; +const NS_HTTP_ON_USERAGENT_REQUEST_TOPIC = "http-on-useragent-request"; + XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "UserAgentOverrides", "resource://gre/modules/UserAgentOverrides.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "eTLDService", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"); class UAOverrider { @@ -33,14 +35,24 @@ class UAOverrider { } init() { - UserAgentOverrides.addComplexOverride(this.overrideCallback.bind(this)); + Services.obs.addObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC); } - overrideCallback(channel, defaultUA) { - let uaOverride = this.lookupUAOverride(channel.URI, defaultUA); + uninit() { + Services.obs.removeObserver(this, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC); + } + + observe(subject, topic) { + if (topic !== NS_HTTP_ON_USERAGENT_REQUEST_TOPIC) { + return; + } + + let channel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); + let uaOverride = this.lookupUAOverride(channel.URI); + if (uaOverride) { console.log("The user agent has been overridden for compatibility reasons."); - return uaOverride; + channel.setRequestHeader("User-Agent", uaOverride, false); } } @@ -76,12 +88,12 @@ class UAOverrider { * If there are more than one possible overrides, that is if two or more * uriMatchers would return true, the first one gets applied. */ - lookupUAOverride(uri, defaultUA) { + lookupUAOverride(uri) { let baseDomain = this.getBaseDomainFromURI(uri); if (baseDomain && this._overrides[baseDomain]) { for (let uaOverride of this._overrides[baseDomain]) { if (uaOverride.uriMatcher(uri.specIgnoringRef)) { - return uaOverride.uaTransformer(defaultUA); + return uaOverride.uaTransformer(DefaultUA); } } } From 71f3e232a77a96738eea0a9863749da7c17ece6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fausto=20N=C3=BA=C3=B1ez=20Alberro?= Date: Wed, 9 Aug 2017 20:34:04 -0500 Subject: [PATCH 125/166] servo: Merge #17812 - Introduce ComputedUrl (from brainlessdeveloper:use-resolved-url-instead-of-original); r=emilio Use the new `ComputedUrl` type for computed types and `SpecifiedUrl` for specified types instead of using the `SpecifiedUrl` implementation for both. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #17625 (github issue number if applicable). - [ ] There are tests for these changes OR - [x] These changes do not require tests because this is an implementation change and tests already exist. Source-Repo: https://github.com/servo/servo Source-Revision: 8a48578a2601769d61ab6f8429e7b1ecb19cbb84 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 8e64001c6f6116b88cf25e54bdcfaa5632a83539 --- .../helpers/animated_properties.mako.rs | 6 +-- servo/components/style/servo/url.rs | 33 +++++++++++++ servo/components/style/values/animated/mod.rs | 4 ++ .../style/values/computed/basic_shape.rs | 6 +-- .../components/style/values/computed/image.rs | 6 +-- servo/components/style/values/computed/mod.rs | 49 ++++++++++++++++++- servo/components/style/values/computed/svg.rs | 5 +- .../style/values/generics/basic_shape.rs | 11 ++--- .../components/style/values/generics/image.rs | 19 ++++--- servo/components/style/values/generics/svg.rs | 15 +++--- .../style/values/specified/basic_shape.rs | 6 +-- .../style/values/specified/image.rs | 4 +- .../components/style/values/specified/mod.rs | 3 +- .../components/style/values/specified/svg.rs | 6 +-- 14 files changed, 127 insertions(+), 46 deletions(-) diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index 88dc2272f004..07031c2f67a8 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -44,7 +44,7 @@ use values::animated::effects::FilterList as AnimatedFilterList; use values::animated::effects::TextShadowList as AnimatedTextShadowList; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderCornerRadius, ClipRect}; -use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified}; +use values::computed::{CalcLengthOrPercentage, Color, Context, ComputedValueAsSpecified, ComputedUrl}; use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue}; use values::computed::{NonNegativeAu, NonNegativeNumber, PositiveIntegerOrAuto}; use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal}; @@ -2974,10 +2974,10 @@ impl ToAnimatedZero for IntermediateColor { } /// Animatable SVGPaint -pub type IntermediateSVGPaint = SVGPaint; +pub type IntermediateSVGPaint = SVGPaint; /// Animatable SVGPaintKind -pub type IntermediateSVGPaintKind = SVGPaintKind; +pub type IntermediateSVGPaintKind = SVGPaintKind; impl Animatable for IntermediateSVGPaint { #[inline] diff --git a/servo/components/style/servo/url.rs b/servo/components/style/servo/url.rs index ef257bacfe32..4736f2967d86 100644 --- a/servo/components/style/servo/url.rs +++ b/servo/components/style/servo/url.rs @@ -12,6 +12,7 @@ use std::fmt; // the threshold. use std::sync::Arc; use style_traits::{ToCss, ParseError}; +use values::computed::{Context, ToComputedValue, ComputedUrl}; /// A specified url() value for servo. /// @@ -126,3 +127,35 @@ impl ToCss for SpecifiedUrl { dest.write_str(")") } } + +impl ToComputedValue for SpecifiedUrl { + type ComputedValue = ComputedUrl; + + // If we can't resolve the URL from the specified one, we fall back to the original + // but still return it as a ComputedUrl::Invalid + fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { + match self.resolved { + Some(ref url) => ComputedUrl::Valid(url.clone()), + None => match self.original { + Some(ref url) => ComputedUrl::Invalid(url.clone()), + None => { + unreachable!("Found specified url with neither resolved or original URI!"); + }, + } + } + } + + fn from_computed_value(computed: &ComputedUrl) -> Self { + match *computed { + ComputedUrl::Valid(ref url) => SpecifiedUrl { + original: None, + resolved: Some(url.clone()), + }, + ComputedUrl::Invalid(ref url) => SpecifiedUrl { + original: Some(url.clone()), + resolved: None, + } + } + } +} + diff --git a/servo/components/style/values/animated/mod.rs b/servo/components/style/values/animated/mod.rs index 49a53938e1e0..464dbf860405 100644 --- a/servo/components/style/values/animated/mod.rs +++ b/servo/components/style/values/animated/mod.rs @@ -13,6 +13,8 @@ use smallvec::SmallVec; use std::cmp::max; use values::computed::Angle as ComputedAngle; use values::computed::BorderCornerRadius as ComputedBorderCornerRadius; +#[cfg(feature = "servo")] +use values::computed::ComputedUrl; use values::computed::GreaterThanOrEqualToOneNumber as ComputedGreaterThanOrEqualToOneNumber; use values::computed::MaxLength as ComputedMaxLength; use values::computed::MozLength as ComputedMozLength; @@ -95,6 +97,8 @@ pub trait AnimatedValueAsComputed {} impl AnimatedValueAsComputed for Au {} impl AnimatedValueAsComputed for ComputedAngle {} impl AnimatedValueAsComputed for SpecifiedUrl {} +#[cfg(feature = "servo")] +impl AnimatedValueAsComputed for ComputedUrl {} impl AnimatedValueAsComputed for bool {} impl AnimatedValueAsComputed for f32 {} diff --git a/servo/components/style/values/computed/basic_shape.rs b/servo/components/style/values/computed/basic_shape.rs index 2b3cebb869b0..b9c82be1fb90 100644 --- a/servo/components/style/values/computed/basic_shape.rs +++ b/servo/components/style/values/computed/basic_shape.rs @@ -9,17 +9,17 @@ use std::fmt; use style_traits::ToCss; -use values::computed::LengthOrPercentage; +use values::computed::{LengthOrPercentage, ComputedUrl}; use values::generics::basic_shape::{BasicShape as GenericBasicShape}; use values::generics::basic_shape::{Circle as GenericCircle, ClippingShape as GenericClippingShape}; use values::generics::basic_shape::{Ellipse as GenericEllipse, FloatAreaShape as GenericFloatAreaShape}; use values::generics::basic_shape::{InsetRect as GenericInsetRect, ShapeRadius as GenericShapeRadius}; /// A specified clipping shape. -pub type ClippingShape = GenericClippingShape; +pub type ClippingShape = GenericClippingShape; /// A specified float area shape. -pub type FloatAreaShape = GenericFloatAreaShape; +pub type FloatAreaShape = GenericFloatAreaShape; /// A computed basic shape. pub type BasicShape = GenericBasicShape; diff --git a/servo/components/style/values/computed/image.rs b/servo/components/style/values/computed/image.rs index dc4a27f205fe..a4a51b7bae6a 100644 --- a/servo/components/style/values/computed/image.rs +++ b/servo/components/style/values/computed/image.rs @@ -12,7 +12,7 @@ use std::f32::consts::PI; use std::fmt; use style_traits::ToCss; use values::{Either, None_}; -use values::computed::{Angle, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; +use values::computed::{Angle, ComputedUrl, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; use values::computed::position::Position; use values::generics::image::{CompatMode, ColorStop as GenericColorStop, EndingShape as GenericEndingShape}; use values::generics::image::{Gradient as GenericGradient, GradientItem as GenericGradientItem}; @@ -27,7 +27,7 @@ pub type ImageLayer = Either; /// Computed values for an image according to CSS-IMAGES. /// https://drafts.csswg.org/css-images/#image-values -pub type Image = GenericImage; +pub type Image = GenericImage; /// Computed values for a CSS gradient. /// https://drafts.csswg.org/css-images/#gradients @@ -76,7 +76,7 @@ pub type GradientItem = GenericGradientItem; pub type ColorStop = GenericColorStop; /// Computed values for `-moz-image-rect(...)`. -pub type MozImageRect = GenericMozImageRect; +pub type MozImageRect = GenericMozImageRect; impl GenericLineDirection for LineDirection { fn points_downwards(&self) -> bool { diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index 104c0fcd14aa..75b9e3bb3545 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -12,10 +12,14 @@ use media_queries::Device; #[cfg(feature = "gecko")] use properties; use properties::{ComputedValues, StyleBuilder}; +#[cfg(feature = "servo")] +use servo_url::ServoUrl; use std::f32; use std::f64; use std::f64::consts::PI; use std::fmt; +#[cfg(feature = "servo")] +use std::sync::Arc; use style_traits::ToCss; use super::{CSSFloat, CSSInteger}; use super::generics::{GreaterThanOrEqualToOne, NonNegative}; @@ -39,9 +43,8 @@ pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, pub use self::gecko::ScrollSnapPoint; pub use self::rect::LengthOrNumberRect; pub use super::{Auto, Either, None_}; -pub use super::specified::{BorderStyle, UrlOrNone}; +pub use super::specified::BorderStyle; pub use super::generics::grid::GridLine; -pub use super::specified::url::SpecifiedUrl; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage}; pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::NonNegativeLengthOrPercentage; @@ -683,3 +686,45 @@ impl ToComputedValue for specified::Percentage { specified::Percentage::new(computed.0) } } + +/// The computed value of a CSS `url()`, resolved relative to the stylesheet URL. +#[cfg(feature = "servo")] +#[derive(Clone, Debug, HeapSizeOf, Serialize, Deserialize, PartialEq)] +pub enum ComputedUrl { + /// The `url()` was invalid or it wasn't specified by the user. + Invalid(Arc), + /// The resolved `url()` relative to the stylesheet URL. + Valid(ServoUrl), +} + +/// TODO: Properly build ComputedUrl for gecko +#[cfg(feature = "gecko")] +pub type ComputedUrl = specified::url::SpecifiedUrl; + +#[cfg(feature = "servo")] +impl ComputedUrl { + /// Returns the resolved url if it was valid. + pub fn url(&self) -> Option<&ServoUrl> { + match *self { + ComputedUrl::Valid(ref url) => Some(url), + _ => None, + } + } +} + +#[cfg(feature = "servo")] +impl ToCss for ComputedUrl { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let string = match *self { + ComputedUrl::Valid(ref url) => url.as_str(), + ComputedUrl::Invalid(ref invalid_string) => invalid_string, + }; + + dest.write_str("url(")?; + string.to_css(dest)?; + dest.write_str(")") + } +} + +/// | +pub type UrlOrNone = Either; diff --git a/servo/components/style/values/computed/svg.rs b/servo/components/style/values/computed/svg.rs index 43613baa8c43..88cdbd5009e7 100644 --- a/servo/components/style/values/computed/svg.rs +++ b/servo/components/style/values/computed/svg.rs @@ -8,12 +8,13 @@ use app_units::Au; use values::{Either, RGBA}; use values::computed::{LengthOrPercentageOrNumber, Opacity}; use values::computed::{NonNegativeAu, NonNegativeLengthOrPercentageOrNumber}; +use values::computed::ComputedUrl; use values::generics::svg as generic; /// Computed SVG Paint value -pub type SVGPaint = generic::SVGPaint; +pub type SVGPaint = generic::SVGPaint; /// Computed SVG Paint Kind value -pub type SVGPaintKind = generic::SVGPaintKind; +pub type SVGPaintKind = generic::SVGPaintKind; impl Default for SVGPaint { fn default() -> Self { diff --git a/servo/components/style/values/generics/basic_shape.rs b/servo/components/style/values/generics/basic_shape.rs index e7cfdbd25fe3..98f9cd7690b6 100644 --- a/servo/components/style/values/generics/basic_shape.rs +++ b/servo/components/style/values/generics/basic_shape.rs @@ -11,10 +11,9 @@ use values::computed::ComputedValueAsSpecified; use values::generics::border::BorderRadius; use values::generics::position::Position; use values::generics::rect::Rect; -use values::specified::url::SpecifiedUrl; /// A clipping shape, for `clip-path`. -pub type ClippingShape = ShapeSource; +pub type ClippingShape = ShapeSource; /// https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box #[allow(missing_docs)] @@ -29,7 +28,7 @@ pub enum GeometryBox { impl ComputedValueAsSpecified for GeometryBox {} /// A float area shape, for `shape-outside`. -pub type FloatAreaShape = ShapeSource; +pub type FloatAreaShape = ShapeSource; // https://drafts.csswg.org/css-shapes-1/#typedef-shape-box define_css_keyword_enum!(ShapeBox: @@ -44,8 +43,8 @@ add_impls_for_keyword_enum!(ShapeBox); #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)] -pub enum ShapeSource { - Url(SpecifiedUrl), +pub enum ShapeSource { + Url(UrlShapeSource), Shape(BasicShape, Option), Box(ReferenceBox), None, @@ -121,7 +120,7 @@ define_css_keyword_enum!(FillRule: ); add_impls_for_keyword_enum!(FillRule); -impl HasViewportPercentage for ShapeSource { +impl HasViewportPercentage for ShapeSource { #[inline] fn has_viewport_percentage(&self) -> bool { false } } diff --git a/servo/components/style/values/generics/image.rs b/servo/components/style/values/generics/image.rs index 5da5a68563cc..867364e3df35 100644 --- a/servo/components/style/values/generics/image.rs +++ b/servo/components/style/values/generics/image.rs @@ -12,16 +12,15 @@ use custom_properties::SpecifiedValue; use std::fmt; use style_traits::{HasViewportPercentage, ToCss}; use values::computed::ComputedValueAsSpecified; -use values::specified::url::SpecifiedUrl; /// An [image]. /// /// [image]: https://drafts.csswg.org/css-images/#image-values #[derive(Clone, PartialEq, ToComputedValue)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum Image { +pub enum Image { /// A `` image. - Url(SpecifiedUrl), + Url(ImageUrl), /// A `` image. Gradient(Gradient), /// A `-moz-image-rect` image @@ -168,16 +167,16 @@ impl ToCss for PaintWorklet { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[css(comma, function)] #[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)] -pub struct MozImageRect { - pub url: SpecifiedUrl, +pub struct MozImageRect { + pub url: MozImageRectUrl, pub top: NumberOrPercentage, pub right: NumberOrPercentage, pub bottom: NumberOrPercentage, pub left: NumberOrPercentage, } -impl fmt::Debug for Image - where G: fmt::Debug, R: fmt::Debug, +impl fmt::Debug for Image + where G: fmt::Debug, R: fmt::Debug, U: fmt::Debug + ToCss { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -195,8 +194,8 @@ impl fmt::Debug for Image } } -impl ToCss for Image - where G: ToCss, R: ToCss, +impl ToCss for Image + where G: ToCss, R: ToCss, U: ToCss { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -214,7 +213,7 @@ impl ToCss for Image } } -impl HasViewportPercentage for Image +impl HasViewportPercentage for Image where G: HasViewportPercentage { fn has_viewport_percentage(&self) -> bool { diff --git a/servo/components/style/values/generics/svg.rs b/servo/components/style/values/generics/svg.rs index 557a63fd24c4..05e0e66248fa 100644 --- a/servo/components/style/values/generics/svg.rs +++ b/servo/components/style/values/generics/svg.rs @@ -8,16 +8,15 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; use style_traits::{ParseError, StyleParseError, ToCss}; -use values::specified::url::SpecifiedUrl; /// An SVG paint value /// /// https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Debug, PartialEq, ToAnimatedValue, ToComputedValue, ToCss)] -pub struct SVGPaint { +pub struct SVGPaint { /// The paint source - pub kind: SVGPaintKind, + pub kind: SVGPaintKind, /// The fallback color pub fallback: Option, } @@ -29,20 +28,20 @@ pub struct SVGPaint { /// properties have a fallback as well. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, Debug, PartialEq, ToAnimatedValue, ToComputedValue, ToCss)] -pub enum SVGPaintKind { +pub enum SVGPaintKind { /// `none` None, /// `` Color(ColorType), /// `url(...)` - PaintServer(SpecifiedUrl), + PaintServer(UrlPaintServer), /// `context-fill` ContextFill, /// `context-stroke` ContextStroke, } -impl SVGPaintKind { +impl SVGPaintKind { /// Parse a keyword value only fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { try_match_ident_ignore_ascii_case! { input.expect_ident()?, @@ -66,9 +65,9 @@ fn parse_fallback<'i, 't, ColorType: Parse>(context: &ParserContext, } } -impl Parse for SVGPaint { +impl Parse for SVGPaint { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) { + if let Ok(url) = input.try(|i| UrlPaintServer::parse(context, i)) { Ok(SVGPaint { kind: SVGPaintKind::PaintServer(url), fallback: parse_fallback(context, input), diff --git a/servo/components/style/values/specified/basic_shape.rs b/servo/components/style/values/specified/basic_shape.rs index 4ce3adb29688..cabed5994ed9 100644 --- a/servo/components/style/values/specified/basic_shape.rs +++ b/servo/components/style/values/specified/basic_shape.rs @@ -26,10 +26,10 @@ use values::specified::position::{HorizontalPosition, Position, PositionComponen use values::specified::url::SpecifiedUrl; /// A specified clipping shape. -pub type ClippingShape = GenericClippingShape; +pub type ClippingShape = GenericClippingShape; /// A specified float area shape. -pub type FloatAreaShape = GenericFloatAreaShape; +pub type FloatAreaShape = GenericFloatAreaShape; /// A specified basic shape. pub type BasicShape = GenericBasicShape; @@ -49,7 +49,7 @@ pub type ShapeRadius = GenericShapeRadius; /// The specified value of `Polygon` pub type Polygon = GenericPolygon; -impl Parse for ShapeSource { +impl Parse for ShapeSource { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { if input.try(|i| i.expect_ident_matching("none")).is_ok() { return Ok(ShapeSource::None) diff --git a/servo/components/style/values/specified/image.rs b/servo/components/style/values/specified/image.rs index 687c6f17d432..42f440433289 100644 --- a/servo/components/style/values/specified/image.rs +++ b/servo/components/style/values/specified/image.rs @@ -38,7 +38,7 @@ pub type ImageLayer = Either; /// Specified values for an image according to CSS-IMAGES. /// https://drafts.csswg.org/css-images/#image-values -pub type Image = GenericImage; +pub type Image = GenericImage; /// Specified values for a CSS gradient. /// https://drafts.csswg.org/css-images/#gradients @@ -125,7 +125,7 @@ pub type ColorStop = GenericColorStop; /// Specified values for `moz-image-rect` /// -moz-image-rect(, top, right, bottom, left); -pub type MozImageRect = GenericMozImageRect; +pub type MozImageRect = GenericMozImageRect; impl Parse for Image { #[cfg_attr(not(feature = "gecko"), allow(unused_mut))] diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs index 0c95e9a3693f..e8bfad406ad8 100644 --- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -76,6 +76,7 @@ pub mod url { use cssparser::Parser; use parser::{Parse, ParserContext}; use style_traits::ParseError; +#[cfg(feature = "gecko")] use values::computed::ComputedValueAsSpecified; #[cfg(feature = "servo")] @@ -92,7 +93,7 @@ impl Parse for SpecifiedUrl { impl Eq for SpecifiedUrl {} -// TODO(emilio): Maybe consider ComputedUrl to save a word in style structs? +#[cfg(feature = "gecko")] impl ComputedValueAsSpecified for SpecifiedUrl {} no_viewport_percentage!(SpecifiedUrl); diff --git a/servo/components/style/values/specified/svg.rs b/servo/components/style/values/specified/svg.rs index 8ee5736bbd71..980162ccd2da 100644 --- a/servo/components/style/values/specified/svg.rs +++ b/servo/components/style/values/specified/svg.rs @@ -8,16 +8,16 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError}; use values::generics::svg as generic; -use values::specified::{LengthOrPercentageOrNumber, NonNegativeLengthOrPercentageOrNumber, Opacity}; +use values::specified::{LengthOrPercentageOrNumber, NonNegativeLengthOrPercentageOrNumber, Opacity, SpecifiedUrl}; use values::specified::color::RGBAColor; /// Specified SVG Paint value -pub type SVGPaint = generic::SVGPaint; +pub type SVGPaint = generic::SVGPaint; no_viewport_percentage!(SVGPaint); /// Specified SVG Paint Kind value -pub type SVGPaintKind = generic::SVGPaintKind; +pub type SVGPaintKind = generic::SVGPaintKind; #[cfg(feature = "gecko")] fn is_context_value_enabled() -> bool { From 32951f48245ae070ec7135e1c40683f8137133bf Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 9 Aug 2017 11:06:29 +0800 Subject: [PATCH 126/166] Bug 1388604 - move SetReadMode() from MediaResource to BaseMediaResource. r=gerald It would be less accurate to call SetReadMode(MediaCacheStream::MODE_PLAYBACK) in ChannelMediaDecoder::MetadataLoaded() instead of DecodeMetadataState::OnMetadataRead() because MDSM might have started decoding by the time 'metadata loaded' event arrives in the main thread. However this little inaccuracy should be fine since it only affects a small amount of data concerning the eviction algorithm. MozReview-Commit-ID: JoQMGr5Fvge --HG-- extra : rebase_source : 3663a028522cc8b973964f62e59d7568a5eba10a extra : source : 359b4454633432d3334a106aedb267a2451afb45 --- dom/media/BufferMediaResource.h | 2 -- dom/media/ChannelMediaDecoder.cpp | 14 ++++++++++++++ dom/media/ChannelMediaDecoder.h | 4 ++++ dom/media/MediaDecoder.h | 12 ++++++------ dom/media/MediaDecoderStateMachine.cpp | 6 ------ dom/media/MediaResource.h | 5 +++-- dom/media/gtest/MockMediaResource.h | 1 - dom/media/hls/HLSResource.h | 1 - dom/media/mediasource/MediaSourceResource.h | 1 - dom/media/mediasource/SourceBufferResource.h | 4 ---- 10 files changed, 27 insertions(+), 23 deletions(-) diff --git a/dom/media/BufferMediaResource.h b/dom/media/BufferMediaResource.h index cfd6b57890cd..12ad29026d59 100644 --- a/dom/media/BufferMediaResource.h +++ b/dom/media/BufferMediaResource.h @@ -43,8 +43,6 @@ private: return principal.forget(); } // These methods are called off the main thread. - // The mode is initially MODE_PLAYBACK. - void SetReadMode(MediaCacheStream::ReadMode aMode) override {} nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { diff --git a/dom/media/ChannelMediaDecoder.cpp b/dom/media/ChannelMediaDecoder.cpp index 26b8c73faea8..df6ec058eb82 100644 --- a/dom/media/ChannelMediaDecoder.cpp +++ b/dom/media/ChannelMediaDecoder.cpp @@ -254,6 +254,9 @@ ChannelMediaDecoder::Load(nsIChannel* aChannel, rv = OpenResource(aStreamListener); NS_ENSURE_SUCCESS(rv, rv); + // Set mode to METADATA since we are about to read metadata. + mResource->SetReadMode(MediaCacheStream::MODE_METADATA); + SetStateMachine(CreateStateMachine()); NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE); @@ -501,6 +504,17 @@ ChannelMediaDecoder::Resume() } } +void +ChannelMediaDecoder::MetadataLoaded( + UniquePtr aInfo, + UniquePtr aTags, + MediaDecoderEventVisibility aEventVisibility) +{ + MediaDecoder::MetadataLoaded(Move(aInfo), Move(aTags), aEventVisibility); + // Set mode to PLAYBACK after reading metadata. + mResource->SetReadMode(MediaCacheStream::MODE_PLAYBACK); +} + } // namespace mozilla // avoid redefined macro in unified build diff --git a/dom/media/ChannelMediaDecoder.h b/dom/media/ChannelMediaDecoder.h index 69d7c43c8b10..37e6cfee1bd0 100644 --- a/dom/media/ChannelMediaDecoder.h +++ b/dom/media/ChannelMediaDecoder.h @@ -57,6 +57,10 @@ protected: void OnPlaybackEvent(MediaEventType aEvent) override; void DurationChanged() override; void DownloadProgressed() override; + void MetadataLoaded(UniquePtr aInfo, + UniquePtr aTags, + MediaDecoderEventVisibility aEventVisibility) override; + RefPtr mResourceCallback; RefPtr mResource; diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index f73162dafead..15ad956add7d 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -456,6 +456,12 @@ protected: virtual void OnPlaybackEvent(MediaEventType aEvent); + // Called when the metadata from the media file has been loaded by the + // state machine. Call on the main thread only. + virtual void MetadataLoaded(UniquePtr aInfo, + UniquePtr aTags, + MediaDecoderEventVisibility aEventVisibility); + /****** * The following members should be accessed with the decoder lock held. ******/ @@ -496,12 +502,6 @@ protected: private: nsCString GetDebugInfo(); - // Called when the metadata from the media file has been loaded by the - // state machine. Call on the main thread only. - void MetadataLoaded(UniquePtr aInfo, - UniquePtr aTags, - MediaDecoderEventVisibility aEventVisibility); - // Called when the owner's activity changed. void NotifyCompositor(); diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 4e65f1818c38..48598cb0941a 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -341,9 +341,6 @@ public: MOZ_ASSERT(!mMetadataRequest.Exists()); SLOG("Dispatching AsyncReadMetadata"); - // Set mode to METADATA since we are about to read metadata. - Resource()->SetReadMode(MediaCacheStream::MODE_METADATA); - // We disconnect mMetadataRequest in Exit() so it is fine to capture // a raw pointer here. Reader()->ReadMetadata() @@ -2224,9 +2221,6 @@ DecodeMetadataState::OnMetadataRead(MetadataHolder&& aMetadata) { mMetadataRequest.Complete(); - // Set mode to PLAYBACK after reading metadata. - Resource()->SetReadMode(MediaCacheStream::MODE_PLAYBACK); - mMaster->mInfo.emplace(*aMetadata.mInfo); mMaster->mMediaSeekable = Info().mMediaSeekable; mMaster->mMediaSeekableOnlyInBufferedRanges = diff --git a/dom/media/MediaResource.h b/dom/media/MediaResource.h index b5a98280780e..4e37de5edd6b 100644 --- a/dom/media/MediaResource.h +++ b/dom/media/MediaResource.h @@ -164,8 +164,6 @@ public: virtual already_AddRefed GetCurrentPrincipal() = 0; // These methods are called off the main thread. - // The mode is initially MODE_PLAYBACK. - virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0; // Read up to aCount bytes from the stream. The read starts at // aOffset in the stream, seeking to that location initially if // it is not the current stream offset. The remaining arguments, @@ -325,6 +323,9 @@ public: // Resume any downloads that have been suspended. virtual void Resume() = 0; + // The mode is initially MODE_PLAYBACK. + virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0; + /** * Open the stream. This creates a stream listener and returns it in * aStreamListener; this listener needs to be notified of incoming data. diff --git a/dom/media/gtest/MockMediaResource.h b/dom/media/gtest/MockMediaResource.h index 451ae9e87988..7e32d95b3744 100644 --- a/dom/media/gtest/MockMediaResource.h +++ b/dom/media/gtest/MockMediaResource.h @@ -20,7 +20,6 @@ public: { return nullptr; } - void SetReadMode(MediaCacheStream::ReadMode aMode) override {} nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override; // Data stored in file, caching recommended. diff --git a/dom/media/hls/HLSResource.h b/dom/media/hls/HLSResource.h index a71a11367837..a3e09dadd4cf 100644 --- a/dom/media/hls/HLSResource.h +++ b/dom/media/hls/HLSResource.h @@ -48,7 +48,6 @@ public: ~HLSResource(); void Suspend(); void Resume(); - void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); } nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; } bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; } int64_t Tell() override { UNIMPLEMENTED(); return -1; } diff --git a/dom/media/mediasource/MediaSourceResource.h b/dom/media/mediasource/MediaSourceResource.h index f69c3a107f85..5ef853ece639 100644 --- a/dom/media/mediasource/MediaSourceResource.h +++ b/dom/media/mediasource/MediaSourceResource.h @@ -32,7 +32,6 @@ public: , mEnded(false) {} - void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); } nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; } bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; } int64_t Tell() override { UNIMPLEMENTED(); return -1; } diff --git a/dom/media/mediasource/SourceBufferResource.h b/dom/media/mediasource/SourceBufferResource.h index 1090396eddd5..f8712a22df10 100644 --- a/dom/media/mediasource/SourceBufferResource.h +++ b/dom/media/mediasource/SourceBufferResource.h @@ -45,10 +45,6 @@ public: UNIMPLEMENTED(); return nullptr; } - void SetReadMode(MediaCacheStream::ReadMode aMode) override - { - UNIMPLEMENTED(); - } nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, From af3ce851d614c936c3bcdf27a94a680adcf18edb Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 9 Aug 2017 16:07:53 +0800 Subject: [PATCH 127/166] Bug 1388612. P1 - remove MediaResource::EnsureCacheUpToDate(). r=gerald This is a workaround to fix bug 687972. It should be OK now to remove it since we have fix bug 1108960 where MediaCache failed to run the update loop to update the suspend status of the stream. MozReview-Commit-ID: MbInehhScs --HG-- extra : rebase_source : 94345a00af31834db8b9858cdf5a9e889044156a extra : source : 70f626894c3a15c8077f70425a97004478caa9e1 --- dom/media/MediaCache.cpp | 8 -------- dom/media/MediaCache.h | 5 ----- dom/media/MediaDecoder.cpp | 3 --- dom/media/MediaResource.cpp | 6 ------ dom/media/MediaResource.h | 4 ---- 5 files changed, 26 deletions(-) diff --git a/dom/media/MediaCache.cpp b/dom/media/MediaCache.cpp index 17c68420cb1b..8c879544e7b2 100644 --- a/dom/media/MediaCache.cpp +++ b/dom/media/MediaCache.cpp @@ -2124,14 +2124,6 @@ MediaCacheStream::Close() mMediaCache->QueueUpdate(); } -void -MediaCacheStream::EnsureCacheUpdate() -{ - if (mHasHadUpdate) - return; - mMediaCache->Update(); -} - void MediaCacheStream::CloseInternal(ReentrantMonitorAutoEnter& aReentrantMonitor) { diff --git a/dom/media/MediaCache.h b/dom/media/MediaCache.h index b40e1ab72b5c..d536667a0020 100644 --- a/dom/media/MediaCache.h +++ b/dom/media/MediaCache.h @@ -232,11 +232,6 @@ public: // Get the principal for this stream. Anything accessing the contents of // this stream must have a principal that subsumes this principal. nsIPrincipal* GetCurrentPrincipal() { return mPrincipal; } - // Ensure a global media cache update has run with this stream present. - // This ensures the cache has had a chance to suspend or unsuspend this stream. - // Called only on main thread. This can change the state of streams, fire - // notifications, etc. - void EnsureCacheUpdate(); // These callbacks are called on the main thread by the client // when data has been received via the channel. diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index f3b3a172c903..61f528a04dd9 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -814,9 +814,6 @@ MediaDecoder::FirstFrameLoaded(nsAutoPtr aInfo, Invalidate(); - // This can run cache callbacks. - GetResource()->EnsureCacheUpToDate(); - // The element can run javascript via events // before reaching here, so only change the // state if we're still set to the original diff --git a/dom/media/MediaResource.cpp b/dom/media/MediaResource.cpp index 691fabcb41d8..158decfd00e8 100644 --- a/dom/media/MediaResource.cpp +++ b/dom/media/MediaResource.cpp @@ -975,12 +975,6 @@ ChannelMediaResource::IsDataCachedToEndOfResource(int64_t aOffset) return mCacheStream.IsDataCachedToEndOfStream(aOffset); } -void -ChannelMediaResource::EnsureCacheUpToDate() -{ - mCacheStream.EnsureCacheUpdate(); -} - bool ChannelMediaResource::IsSuspendedByCache() { diff --git a/dom/media/MediaResource.h b/dom/media/MediaResource.h index 4e37de5edd6b..ad1a47b66e2a 100644 --- a/dom/media/MediaResource.h +++ b/dom/media/MediaResource.h @@ -192,9 +192,6 @@ public: // media. // A call to ReadAt will update this position. virtual int64_t Tell() = 0; - // Ensures that the value returned by IsSuspendedByCache below is up to date - // (i.e. the cache has examined this stream at least once). - virtual void EnsureCacheUpToDate() {} // These can be called on any thread. // Cached blocks associated with this stream will not be evicted @@ -508,7 +505,6 @@ public: already_AddRefed CloneData( MediaResourceCallback* aDecoder) override; nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override; - void EnsureCacheUpToDate() override; // Other thread void SetReadMode(MediaCacheStream::ReadMode aMode) override; From ab74a616747b059f25627d38c3ad236dd0b3000a Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 9 Aug 2017 16:13:51 +0800 Subject: [PATCH 128/166] Bug 1388612. P2 - remove the call to NotifySuspendedStatusChanged() in MediaDecoder::FirstFrameLoaded(). r=gerald Following P1, cache suspend status changes will be notified when necessary. If not, it would be a bug that should be fixed. We shouldn't wallpaper the issue by calling NotifySuspendedStatusChanged() manually. MozReview-Commit-ID: 9EbybTiOOIO --HG-- extra : rebase_source : 299e22c6813f4eeb152c4d8140dc295ff856dc1e extra : source : 2b18fe0368c6332d0b5c1e044218a26c75314124 --- dom/media/MediaDecoder.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 61f528a04dd9..8f9c958cea48 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -822,10 +822,6 @@ MediaDecoder::FirstFrameLoaded(nsAutoPtr aInfo, ChangeState(mNextState); } - // Run NotifySuspendedStatusChanged now to give us a chance to notice - // that autoplay should run. - NotifySuspendedStatusChanged(); - // GetOwner()->FirstFrameLoaded() might call us back. Put it at the bottom of // this function to avoid unexpected shutdown from reentrant calls. if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) { From c1f09cc606861ebe9e7dfd1857f70c593d3c6312 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 9 Aug 2017 16:56:41 +0800 Subject: [PATCH 129/166] Bug 1388665 - remove BufferingState::DispatchDecodeTasksIfNeeded(). r=kaku We will dispatch decoding tasks in Handle{Audio,Video}Decoded() instead. See comment 0 for the rationale. MozReview-Commit-ID: 9trJYoMfzJH --HG-- extra : rebase_source : 0fae6eda31571d34268f2dba58a8e5f6cf0dadc9 extra : source : 275964a63b741e4ac0258e714f54f43d5cc6ae0b --- dom/media/MediaDecoderStateMachine.cpp | 33 +++++++------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 48598cb0941a..513d29eab5bf 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -1864,17 +1864,23 @@ public: void HandleAudioDecoded(AudioData* aAudio) override { + mMaster->PushAudio(aAudio); + if (!mMaster->HaveEnoughDecodedAudio()) { + mMaster->RequestAudioData(); + } // This might be the sample we need to exit buffering. // Schedule Step() to check it. - mMaster->PushAudio(aAudio); mMaster->ScheduleStateMachine(); } void HandleVideoDecoded(VideoData* aVideo, TimeStamp aDecodeStart) override { + mMaster->PushVideo(aVideo); + if (!mMaster->HaveEnoughDecodedVideo()) { + mMaster->RequestVideoData(media::TimeUnit()); + } // This might be the sample we need to exit buffering. // Schedule Step() to check it. - mMaster->PushVideo(aVideo); mMaster->ScheduleStateMachine(); } @@ -1921,8 +1927,6 @@ public: } private: - void DispatchDecodeTasksIfNeeded(); - TimeStamp mBufferingStart; // The maximum number of second we spend buffering when we are short on @@ -2536,25 +2540,6 @@ SeekingState::SeekCompleted() GoToNextState(); } -void -MediaDecoderStateMachine:: -BufferingState::DispatchDecodeTasksIfNeeded() -{ - if (mMaster->IsAudioDecoding() - && !mMaster->HaveEnoughDecodedAudio() - && !mMaster->IsRequestingAudioData() - && !mMaster->IsWaitingAudioData()) { - mMaster->RequestAudioData(); - } - - if (mMaster->IsVideoDecoding() - && !mMaster->HaveEnoughDecodedVideo() - && !mMaster->IsRequestingVideoData() - && !mMaster->IsWaitingVideoData()) { - mMaster->RequestVideoData(media::TimeUnit()); - } -} - void MediaDecoderStateMachine:: BufferingState::Step() @@ -2576,11 +2561,9 @@ BufferingState::Step() SLOG("Buffering: wait %ds, timeout in %.3lfs", mBufferingWait, mBufferingWait - elapsed.ToSeconds()); mMaster->ScheduleStateMachineIn(TimeUnit::FromMicroseconds(USECS_PER_S)); - DispatchDecodeTasksIfNeeded(); return; } } else if (mMaster->OutOfDecodedAudio() || mMaster->OutOfDecodedVideo()) { - DispatchDecodeTasksIfNeeded(); MOZ_ASSERT(!mMaster->OutOfDecodedAudio() || mMaster->IsRequestingAudioData() || mMaster->IsWaitingAudioData()); From 4e2c6b0054b683766690f22b317adfaedaaf0c2f Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 10 Aug 2017 13:11:52 +1000 Subject: [PATCH 130/166] Bug 1341102 - Add fuzzy for some styloVsGecko reftests. MozReview-Commit-ID: Etq5HO11V92 --- layout/reftests/css-break/reftest.list | 2 +- layout/reftests/table-background/reftest.list | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/layout/reftests/css-break/reftest.list b/layout/reftests/css-break/reftest.list index 54cfbcbbeefc..7a5f3adc4476 100644 --- a/layout/reftests/css-break/reftest.list +++ b/layout/reftests/css-break/reftest.list @@ -2,7 +2,7 @@ default-preferences pref(layout.css.box-decoration-break.enabled,true) == box-decoration-break-1.html box-decoration-break-1-ref.html fuzzy(1,20) fuzzy-if(skiaContent,1,700) fuzzy-if(webrender,4-4,3273-3273) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html -fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) fuzzy-if(styloVsGecko,1,420) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543 +fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,57,374) fuzzy-if(styloVsGecko,2,1410) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543 random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html == box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html == box-decoration-break-block-margin.html box-decoration-break-block-margin-ref.html diff --git a/layout/reftests/table-background/reftest.list b/layout/reftests/table-background/reftest.list index df2f629d0d7f..e35e9e164990 100644 --- a/layout/reftests/table-background/reftest.list +++ b/layout/reftests/table-background/reftest.list @@ -3,14 +3,14 @@ fuzzy-if(styloVsGecko,5,330) != backgr_border-table-column-group.html empty.html # Bug 1386543 # This seems to be caused by bug 527825 fuzzy-if(styloVsGecko,5,561) asserts-if(gtkWidget,0-12) != backgr_border-table-column.html empty.html # Bug 1386543 -asserts-if(gtkWidget,0-6) != backgr_border-table-quirks.html empty.html +asserts-if(gtkWidget,0-6) fuzzy-if(styloVsGecko&&winWidget,32,88) != backgr_border-table-quirks.html empty.html fuzzy-if(styloVsGecko,1,168) != backgr_border-table-row-group.html empty.html # Bug 1386543 -fuzzy-if(styloVsGecko,1,168) != backgr_border-table-row.html empty.html # Bug 1386543 +fuzzy-if(styloVsGecko,1,178) != backgr_border-table-row.html empty.html # Bug 1386543 != backgr_border-table.html empty.html != backgr_fixed-bg.html empty.html != backgr_index.html empty.html != backgr_layers-hide.html empty.html -!= backgr_layers-opacity.html empty.html +fuzzy-if(styloVsGecko&&cocoaWidget,1,56781) != backgr_layers-opacity.html empty.html != backgr_layers-show.html empty.html != backgr_position-table-cell.html empty.html != backgr_position-table-column-group.html empty.html From b7d6066c45af83ff32b7863e8e573ca067ffac53 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Wed, 2 Aug 2017 17:26:02 -0400 Subject: [PATCH 131/166] Bug 1386643 - Don't respect font smoothing background colors in pushed layers. r=jrmuizel This is an imperfect workaround. Ideally we'd want layout to determine the correct color here: If the pushed layer will end up on something mostly opaque in the outer layer, the font smoothing background color should be transparent (or even a color that approximates that opaque content), and if the pushed layer will end up on transparency in the outer layer, the appropriate font smoothing background color for the outer layer should be used when drawing text in the pushed layer. This workaround causes us to lose subpixel AA in background tabs that have the overflow mask applied to them. For those, using the font smoothing background color in the pushed layer was the right choice. MozReview-Commit-ID: FPufh04EVp3 --HG-- extra : rebase_source : 7a6cb73255bdb7f1b8aba7df60ebe61171275da4 --- gfx/2d/DrawTargetSkia.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 292c6991d6ab..eb90a2625c3c 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -1261,7 +1261,13 @@ DrawTargetSkia::FillGlyphsWithCG(ScaledFont *aFont, return false; } - SetFontSmoothingBackgroundColor(cgContext, mColorSpace, aRenderingOptions); + if (mPushedLayers.empty()) { + // Respect the font smoothing background color, but only if no layer is + // currently pushed, because this color usually describes what's under this + // DrawTarget, and not what's within this DrawTarget under the currently + // pushed layer. + SetFontSmoothingBackgroundColor(cgContext, mColorSpace, aRenderingOptions); + } SetFontColor(cgContext, mColorSpace, aPattern); ScaledFontMac* macFont = static_cast(aFont); From 5bf938ebcd0653a9b674c30ff52a21113ca7424d Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Wed, 9 Aug 2017 21:15:27 -0700 Subject: [PATCH 132/166] Backed out changeset 4c274336b01e (bug 1386964) for unexpected passes in /scroll-anchoring/anchoring-with-bounds-clamping.html MozReview-Commit-ID: Id1MCoaN242 --- browser/themes/shared/tabs.inc.css | 2 ++ .../meta/css/css-values-3/viewport-units-css2-001.html.ini | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index c26c806f5ef8..2dc39d514952 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -6,10 +6,12 @@ :root { --tab-toolbar-navbar-overlap: 1px; +/* Temporarily using the compact tab strip by default because of bug 1386964: --tab-min-height: 33px; } :root[uidensity=compact] { +*/ --tab-min-height: 29px; } diff --git a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini index 5f8aad9ff46c..eed6261f7ab0 100644 --- a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini +++ b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini @@ -7,12 +7,10 @@ if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL [vh length applied to border-top-width] - expected: - if os != "linux": FAIL + expected: FAIL [vmin length applied to border-top-width] - expected: - if os != "linux": FAIL + expected: FAIL [vmax length applied to border-top-width] expected: From b206b3c597a9a16f1940ac39b0a88eeac87df73a Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 10 Aug 2017 08:49:51 +0900 Subject: [PATCH 133/166] Bug 1388935 - Inline chunk_dalloc_mmap into chunk_dealloc. r=njn --HG-- extra : rebase_source : f6abde118d26552a681faf7df302b791d39e466a --- memory/mozjemalloc/mozjemalloc.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/memory/mozjemalloc/mozjemalloc.cpp b/memory/mozjemalloc/mozjemalloc.cpp index b24fc357c487..005afbf0bd47 100644 --- a/memory/mozjemalloc/mozjemalloc.cpp +++ b/memory/mozjemalloc/mozjemalloc.cpp @@ -2170,18 +2170,6 @@ label_return: base_node_dealloc(xprev); } -static bool -chunk_dalloc_mmap(void *chunk, size_t size) -{ - if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) - return true; - - pages_unmap(chunk, size); - return false; -} - -#undef CAN_RECYCLE - static void chunk_dealloc(void *chunk, size_t size, ChunkType type) { @@ -2193,10 +2181,16 @@ chunk_dealloc(void *chunk, size_t size, ChunkType type) malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, nullptr); - if (chunk_dalloc_mmap(chunk, size)) + if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) { chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size, type); + return; + } + + pages_unmap(chunk, size); } +#undef CAN_RECYCLE + /* * End chunk management functions. */ From 44b527c7d707701063b7ebfc383e2e3c68904d97 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 10 Aug 2017 09:22:55 +0900 Subject: [PATCH 134/166] Bug 1388935 - Avoid overflowing the chunk recycling limit with very large chunks. r=njn When recycling chunks, mozjemalloc tries to avoid keeping around more than 128MB worth of chunks around, but it doesn't actually look at the size of the chunks that are recycled, so if chunk larger than 128MB is recycled, it is kept as a whole, going well over the limit. The chunks are still properly reused, and further recycling doesn't occur, but that can limit other mmap users from getting enough address space. With this change, mozjemalloc now doesn't keep more than 128MB, by splitting the chunks it recycles if they are too large. Note this was not a problem on Windows, where chunks larger than 1MB are never recycled (per CAN_RECYCLE). --HG-- extra : rebase_source : f81e94c6960ba253037f77de1a39c9ff74651e80 --- memory/mozjemalloc/mozjemalloc.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/memory/mozjemalloc/mozjemalloc.cpp b/memory/mozjemalloc/mozjemalloc.cpp index 005afbf0bd47..6339f68e0b96 100644 --- a/memory/mozjemalloc/mozjemalloc.cpp +++ b/memory/mozjemalloc/mozjemalloc.cpp @@ -140,6 +140,7 @@ #include #include #include +#include #ifdef MOZ_MEMORY_WINDOWS @@ -148,7 +149,6 @@ #include #include #include -#include #define SIZE_T_MAX SIZE_MAX #define STDERR_FILENO 2 @@ -2181,8 +2181,21 @@ chunk_dealloc(void *chunk, size_t size, ChunkType type) malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, nullptr); - if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) { - chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size, type); + if (CAN_RECYCLE(size)) { + size_t recycled_so_far = load_acquire_z(&recycled_size); + // In case some race condition put us above the limit. + if (recycled_so_far < recycle_limit) { + size_t recycle_remaining = recycle_limit - recycled_so_far; + size_t to_recycle; + if (size > recycle_remaining) { + to_recycle = recycle_remaining; + // Drop pages that would overflow the recycle limit + pages_trim(chunk, size, 0, to_recycle); + } else { + to_recycle = size; + } + chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, to_recycle, type); + } return; } From 092be74b6e1fbcf098442be7f767e3bd79dcb06b Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 10 Aug 2017 14:27:40 +1000 Subject: [PATCH 135/166] Bug 1383992 followup - Update mochitest expectation. MozReview-Commit-ID: C1QKAVJgK9v --- layout/base/tests/mochitest.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 185bcb73fa8d..93a141e39728 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -136,7 +136,6 @@ support-files = bug1226904.html [test_bug1246622.html] [test_bug1278021.html] [test_emulateMedium.html] -fail-if = stylo # bug 1371395 [test_event_target_iframe_oop.html] skip-if = e10s # bug 1020135, nested oop iframes not supported support-files = bug921928_event_target_iframe_apps_oop.html From a0b8a2c68d0f67cc60770f5f9766c47abb929b1d Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 9 Aug 2017 19:57:33 +1000 Subject: [PATCH 136/166] Bug 1370508 - Enable stylo on generic XML documents. r=heycam MozReview-Commit-ID: 4XQ9RPQ7oa1 --HG-- extra : rebase_source : f5ffeaa615076035215f5ac1b9b39aa5cb15d618 --- dom/base/nsDocument.cpp | 3 +-- layout/reftests/w3c-css/failures.list | 4 ++++ layout/reftests/w3c-css/received/reftest.list | 2 +- layout/xul/crashtests/crashtests.list | 2 +- .../web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini | 3 +++ 5 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index b4773160af92..0f3fd562c77f 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -13224,8 +13224,7 @@ nsIDocument::UpdateStyleBackendType() mStyleBackendType = StyleBackendType::Servo; } else if (!mDocumentContainer) { NS_WARNING("stylo: No docshell yet, assuming Gecko style system"); - } else if ((IsHTMLOrXHTML() || IsSVGDocument()) && - IsContentDocument()) { + } else if (!IsXULDocument() && IsContentDocument()) { // Disable stylo for about: pages other than about:blank, since // they tend to use unsupported selectors like XUL tree pseudos. bool isAbout = false; diff --git a/layout/reftests/w3c-css/failures.list b/layout/reftests/w3c-css/failures.list index 966f69ff9ae0..1560f4ad673d 100644 --- a/layout/reftests/w3c-css/failures.list +++ b/layout/reftests/w3c-css/failures.list @@ -314,3 +314,7 @@ fuzzy(255,2808) css-multicol-1/multicol-rule-large-001.xht fails-if(!styloVsGecko) css-multicol-1/multicol-fill-auto-block-children-001.xht fails-if(!styloVsGecko) css-multicol-1/multicol-fill-auto-block-children-002.xht fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-block-sibling-003.xht + +#### CSS Namespaces 3 ############################################## + +fails-if(stylo||styloVsGecko) css-namespaces-3/syntax-013.xml diff --git a/layout/reftests/w3c-css/received/reftest.list b/layout/reftests/w3c-css/received/reftest.list index 16c2fe7ae2c2..8fb03e5853a1 100644 --- a/layout/reftests/w3c-css/received/reftest.list +++ b/layout/reftests/w3c-css/received/reftest.list @@ -205,7 +205,7 @@ fails-if(!styloVsGecko) == css-multicol-1/multicol-zero-height-001.xht css-multi == css-namespaces-3/syntax-010.xml css-namespaces-3/reftest/ref-lime-3.xml == css-namespaces-3/syntax-011.xml css-namespaces-3/reftest/ref-lime-6.xml == css-namespaces-3/syntax-012.xml css-namespaces-3/reftest/ref-lime-3.xml -== css-namespaces-3/syntax-013.xml css-namespaces-3/reftest/ref-lime-5.xml +fails-if(stylo||styloVsGecko) == css-namespaces-3/syntax-013.xml css-namespaces-3/reftest/ref-lime-5.xml # bug 1388911 == css-namespaces-3/syntax-014.xml css-namespaces-3/reftest/ref-lime-3.xml == css-namespaces-3/syntax-015.xml css-namespaces-3/reftest/ref-lime-1.xml fails-if(!styloVsGecko) == css-values-3/attr-color-invalid-cast.html css-values-3/reference/200-200-green.html diff --git a/layout/xul/crashtests/crashtests.list b/layout/xul/crashtests/crashtests.list index c1445cb5ec7a..e60af3526383 100644 --- a/layout/xul/crashtests/crashtests.list +++ b/layout/xul/crashtests/crashtests.list @@ -1,6 +1,6 @@ load 131008-1.xul load 137216-1.xul -load 140218-1.xml +asserts-if(stylo,3) load 140218-1.xml load 151826-1.xul load 168724-1.xul load 189814-1.xul diff --git a/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini b/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini new file mode 100644 index 000000000000..eb1f51d57bba --- /dev/null +++ b/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini @@ -0,0 +1,3 @@ +[syntax-013.xml] + type: reftest + expected: FAIL From b04d5091db7e3d51c987fbd6684eb5253df07fb7 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 9 Aug 2017 18:06:36 +0900 Subject: [PATCH 137/166] Bug 1388638 - Use RAII class for StartBatchChanges/EndBatchChanges. r=masayuki CompositionTransaction forgets to call EndBatchChanges when GetSelectionController returns error, so we should use RAII class instead. MozReview-Commit-ID: HI9kutRVzx6 --HG-- extra : rebase_source : d276f4349c5a64d4610581ae1a76d160841f7d7b --- editor/libeditor/CompositionTransaction.cpp | 7 ++----- editor/libeditor/EditorBase.cpp | 11 ++++------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/editor/libeditor/CompositionTransaction.cpp b/editor/libeditor/CompositionTransaction.cpp index bde53d2e5d65..a1c9b97b6393 100644 --- a/editor/libeditor/CompositionTransaction.cpp +++ b/editor/libeditor/CompositionTransaction.cpp @@ -198,8 +198,7 @@ CompositionTransaction::SetIMESelection(EditorBase& aEditorBase, RefPtr selection = aEditorBase.GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED); - nsresult rv = selection->StartBatchChanges(); - NS_ENSURE_SUCCESS(rv, rv); + SelectionBatcher selectionBatcher(selection); // First, remove all selections of IME composition. static const RawSelectionType kIMESelections[] = { @@ -213,6 +212,7 @@ CompositionTransaction::SetIMESelection(EditorBase& aEditorBase, aEditorBase.GetSelectionController(getter_AddRefs(selCon)); NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + nsresult rv = NS_OK; for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) { nsCOMPtr selectionOfIME; if (NS_FAILED(selCon->GetSelection(kIMESelections[i], @@ -335,9 +335,6 @@ CompositionTransaction::SetIMESelection(EditorBase& aEditorBase, } } - rv = selection->EndBatchChangesInternal(); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to end batch changes"); - return rv; } diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 88372a78c50e..69204d593aa7 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -723,7 +723,7 @@ EditorBase::DoTransaction(Selection* aSelection, nsITransaction* aTxn) RefPtr selection = aSelection ? aSelection : GetSelection(); NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - selection->StartBatchChanges(); + SelectionBatcher selectionBatcher(selection); nsresult rv; if (mTxnMgr) { @@ -732,14 +732,11 @@ EditorBase::DoTransaction(Selection* aSelection, nsITransaction* aTxn) } else { rv = aTxn->DoTransaction(); } - if (NS_SUCCEEDED(rv)) { - DoAfterDoTransaction(aTxn); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } - // no need to check rv here, don't lose result of operation - selection->EndBatchChanges(); - - NS_ENSURE_SUCCESS(rv, rv); + DoAfterDoTransaction(aTxn); } return NS_OK; From fe1932364b18682eb91f2087bcd3e42c63d9fea9 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Wed, 9 Aug 2017 22:21:37 -0700 Subject: [PATCH 138/166] Backed out 2 changesets (bug 1388935) for gtest crashes Backed out changeset 208572c7abae (bug 1388935) Backed out changeset dfb4a15b0c32 (bug 1388935) MozReview-Commit-ID: HRttV7AIlNT --- memory/mozjemalloc/mozjemalloc.cpp | 37 ++++++++++++------------------ 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/memory/mozjemalloc/mozjemalloc.cpp b/memory/mozjemalloc/mozjemalloc.cpp index 6339f68e0b96..b24fc357c487 100644 --- a/memory/mozjemalloc/mozjemalloc.cpp +++ b/memory/mozjemalloc/mozjemalloc.cpp @@ -140,7 +140,6 @@ #include #include #include -#include #ifdef MOZ_MEMORY_WINDOWS @@ -149,6 +148,7 @@ #include #include #include +#include #define SIZE_T_MAX SIZE_MAX #define STDERR_FILENO 2 @@ -2170,6 +2170,18 @@ label_return: base_node_dealloc(xprev); } +static bool +chunk_dalloc_mmap(void *chunk, size_t size) +{ + if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) + return true; + + pages_unmap(chunk, size); + return false; +} + +#undef CAN_RECYCLE + static void chunk_dealloc(void *chunk, size_t size, ChunkType type) { @@ -2181,29 +2193,10 @@ chunk_dealloc(void *chunk, size_t size, ChunkType type) malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, nullptr); - if (CAN_RECYCLE(size)) { - size_t recycled_so_far = load_acquire_z(&recycled_size); - // In case some race condition put us above the limit. - if (recycled_so_far < recycle_limit) { - size_t recycle_remaining = recycle_limit - recycled_so_far; - size_t to_recycle; - if (size > recycle_remaining) { - to_recycle = recycle_remaining; - // Drop pages that would overflow the recycle limit - pages_trim(chunk, size, 0, to_recycle); - } else { - to_recycle = size; - } - chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, to_recycle, type); - } - return; - } - - pages_unmap(chunk, size); + if (chunk_dalloc_mmap(chunk, size)) + chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size, type); } -#undef CAN_RECYCLE - /* * End chunk management functions. */ From 59eb07a88fb7b855798d6e81da481e79247627c7 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 8 Aug 2017 15:47:24 +1200 Subject: [PATCH 139/166] bug 1388656 size to actual used length in nsTArray::SetCapacity() optimization r=padenot MozReview-Commit-ID: BGFliZTx4QL --HG-- extra : rebase_source : b0e8767bc0beb7fb87559d9135c93937ff4b5470 --- dom/media/webaudio/ConvolverNode.cpp | 2 +- dom/media/webaudio/blink/Reverb.cpp | 8 ++++---- dom/media/webaudio/blink/Reverb.h | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index d257ff268a08..a137e3f2a371 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -98,7 +98,7 @@ public: } mReverb = new WebCore::Reverb(mBuffer, mBufferLength, - MaxFFTSize, 2, mUseBackgroundThreads, + MaxFFTSize, mUseBackgroundThreads, mNormalize, mSampleRate); } diff --git a/dom/media/webaudio/blink/Reverb.cpp b/dom/media/webaudio/blink/Reverb.cpp index 4fca0822b6a8..6a5c04c45cda 100644 --- a/dom/media/webaudio/blink/Reverb.cpp +++ b/dom/media/webaudio/blink/Reverb.cpp @@ -77,7 +77,7 @@ static float calculateNormalizationScale(ThreadSharedFloatArrayBufferList* respo return scale; } -Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize, float sampleRate) +Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, bool useBackgroundThreads, bool normalize, float sampleRate) { float scale = 1; @@ -102,7 +102,7 @@ Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulse } initialize(irChannels, impulseResponseBufferLength, - maxFFTSize, numberOfChannels, useBackgroundThreads); + maxFFTSize, useBackgroundThreads); } size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const @@ -122,13 +122,13 @@ size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const void Reverb::initialize(const nsTArray& impulseResponseBuffer, size_t impulseResponseBufferLength, - size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads) + size_t maxFFTSize, bool useBackgroundThreads) { m_impulseResponseLength = impulseResponseBufferLength; // The reverb can handle a mono impulse response and still do stereo processing size_t numResponseChannels = impulseResponseBuffer.Length(); - m_convolvers.SetCapacity(numberOfChannels); + m_convolvers.SetCapacity(numResponseChannels); int convolverRenderPhase = 0; for (size_t i = 0; i < numResponseChannels; ++i) { diff --git a/dom/media/webaudio/blink/Reverb.h b/dom/media/webaudio/blink/Reverb.h index 35e72283dcde..d8b054655983 100644 --- a/dom/media/webaudio/blink/Reverb.h +++ b/dom/media/webaudio/blink/Reverb.h @@ -50,8 +50,7 @@ public: // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread). Reverb(mozilla::ThreadSharedFloatArrayBufferList* impulseResponseBuffer, size_t impulseResponseBufferLength, size_t maxFFTSize, - size_t numberOfChannels, bool useBackgroundThreads, bool normalize, - float sampleRate); + bool useBackgroundThreads, bool normalize, float sampleRate); void process(const mozilla::AudioBlock* sourceBus, mozilla::AudioBlock* destinationBus); @@ -63,7 +62,7 @@ public: private: void initialize(const nsTArray& impulseResponseBuffer, size_t impulseResponseBufferLength, size_t maxFFTSize, - size_t numberOfChannels, bool useBackgroundThreads); + bool useBackgroundThreads); size_t m_impulseResponseLength; From 35b76397c677fe161554530577b12f6c86250f00 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 8 Aug 2017 15:56:09 +1200 Subject: [PATCH 140/166] bug 1388656 remove unused SAMPLE_RATE SetInt32Parameter case r=padenot Sample rate is passed as a double. MozReview-Commit-ID: DBCvrCWPlgf --HG-- extra : rebase_source : 58812c4a69c5b8dacd2fbee81405f5d97132ed1d --- dom/media/webaudio/ConvolverNode.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index a137e3f2a371..7d80d7f8077d 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -54,9 +54,6 @@ public: mBufferLength = aParam; mLeftOverData = INT32_MIN; break; - case SAMPLE_RATE: - mSampleRate = aParam; - break; case NORMALIZE: mNormalize = !!aParam; break; From 0b158fb300c72191099f6ebbb34d9fb2b9cc493e Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 8 Aug 2017 16:01:57 +1200 Subject: [PATCH 141/166] bug 1388656 re-initialize the Reverb only once when the ConvolverNode buffer changes r=padenot MozReview-Commit-ID: IKMK5GYVRBB --HG-- extra : rebase_source : 03c234254e2eafe6899ed1b51634810db1b38f90 --- dom/media/webaudio/ConvolverNode.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 7d80d7f8077d..045cd9680333 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -66,7 +66,8 @@ public: switch (aIndex) { case SAMPLE_RATE: mSampleRate = aParam; - AdjustReverb(); + // The buffer is passed after the sample rate. + // mReverb will be set using this sample rate when the buffer is received. break; default: NS_ERROR("Bad ConvolverNodeEngine DoubleParameter"); @@ -75,11 +76,7 @@ public: void SetBuffer(already_AddRefed aBuffer) override { mBuffer = aBuffer; - AdjustReverb(); - } - void AdjustReverb() - { // Note about empirical tuning (this is copied from Blink) // The maximum FFT size affects reverb performance and accuracy. // If the reverb is single-threaded and processes entirely in the real-time audio thread, From 46ad6041ffb6abd522d28584bf0bc2466b8e6c81 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Tue, 8 Aug 2017 16:08:21 +1200 Subject: [PATCH 142/166] bug 1388656 keep response buffer on graph thread only long enough to initialize the Reverb r=padenot MozReview-Commit-ID: 6DvpXeWPGHp --HG-- extra : rebase_source : 50a2f7e4df207d971894189d9de8844fab0a7954 --- dom/media/webaudio/ConvolverNode.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 045cd9680333..5cb67a0bdfff 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -49,7 +49,6 @@ public: case BUFFER_LENGTH: // BUFFER_LENGTH is the first parameter that we set when setting a new buffer, // so we should be careful to invalidate the rest of our state here. - mBuffer = nullptr; mSampleRate = 0.0f; mBufferLength = aParam; mLeftOverData = INT32_MIN; @@ -75,7 +74,7 @@ public: } void SetBuffer(already_AddRefed aBuffer) override { - mBuffer = aBuffer; + RefPtr buffer = aBuffer; // Note about empirical tuning (this is copied from Blink) // The maximum FFT size affects reverb performance and accuracy. @@ -85,13 +84,13 @@ public: // Very large FFTs will have worse phase errors. Given these constraints 32768 is a good compromise. const size_t MaxFFTSize = 32768; - if (!mBuffer || !mBufferLength || !mSampleRate) { + if (!buffer || !mBufferLength || !mSampleRate) { mReverb = nullptr; mLeftOverData = INT32_MIN; return; } - mReverb = new WebCore::Reverb(mBuffer, mBufferLength, + mReverb = new WebCore::Reverb(buffer, mBufferLength, MaxFFTSize, mUseBackgroundThreads, mNormalize, mSampleRate); } @@ -159,9 +158,6 @@ public: size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); - if (mBuffer && !mBuffer->IsShared()) { - amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf); - } if (mReverb) { amount += mReverb->sizeOfIncludingThis(aMallocSizeOf); @@ -176,7 +172,6 @@ public: } private: - RefPtr mBuffer; nsAutoPtr mReverb; int32_t mBufferLength; int32_t mLeftOverData; From 614fee5117f8e17ed57bda71f317764cfdc2d7fb Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Wed, 9 Aug 2017 16:52:01 +1200 Subject: [PATCH 143/166] bug 1024182 remove unnecessary buffer copy for short impulse responses r=padenot Despite the comment, this was necessary only for a direct convolver stage, which has been removed: https://hg.mozilla.org/mozilla-central/rev/e66105937eef190dec073f1b9859e07a0272706b#l4.29 FFT convolver stages pad the buffer to the necessary length in FFTBlock::PadAndMakeScaledDFT(). MozReview-Commit-ID: LqP1x1hmLOM --HG-- extra : rebase_source : 622e16140b62ca748a31cbd318f881c617baf17a --- dom/media/webaudio/ConvolverNode.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 5cb67a0bdfff..f81860cad23f 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -272,23 +272,6 @@ ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv) uint32_t length = mBuffer->Length(); RefPtr data = mBuffer->GetThreadSharedChannelsForRate(aCx); - if (data && length < WEBAUDIO_BLOCK_SIZE) { - // For very small impulse response buffers, we need to pad the - // buffer with 0 to make sure that the Reverb implementation - // has enough data to compute FFTs from. - length = WEBAUDIO_BLOCK_SIZE; - RefPtr paddedBuffer = - new ThreadSharedFloatArrayBufferList(data->GetChannels()); - void* channelData = malloc(sizeof(float) * length * data->GetChannels() + 15); - float* alignedChannelData = ALIGNED16(channelData); - ASSERT_ALIGNED16(alignedChannelData); - for (uint32_t i = 0; i < data->GetChannels(); ++i) { - PodCopy(alignedChannelData + length * i, data->GetData(i), mBuffer->Length()); - PodZero(alignedChannelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length()); - paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, alignedChannelData); - } - data = paddedBuffer; - } SendInt32ParameterToStream(ConvolverNodeEngine::BUFFER_LENGTH, length); SendDoubleParameterToStream(ConvolverNodeEngine::SAMPLE_RATE, mBuffer->SampleRate()); From b0f25043736cf0ec1839d074ed2e8ec0a03384df Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 10 Aug 2017 08:49:51 +0900 Subject: [PATCH 144/166] Bug 1388935 - Inline chunk_dalloc_mmap into chunk_dealloc. r=njn --HG-- extra : rebase_source : 3348f221f1f577c3af6c1b213a692e58ce347ead --- memory/mozjemalloc/mozjemalloc.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/memory/mozjemalloc/mozjemalloc.cpp b/memory/mozjemalloc/mozjemalloc.cpp index b24fc357c487..005afbf0bd47 100644 --- a/memory/mozjemalloc/mozjemalloc.cpp +++ b/memory/mozjemalloc/mozjemalloc.cpp @@ -2170,18 +2170,6 @@ label_return: base_node_dealloc(xprev); } -static bool -chunk_dalloc_mmap(void *chunk, size_t size) -{ - if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) - return true; - - pages_unmap(chunk, size); - return false; -} - -#undef CAN_RECYCLE - static void chunk_dealloc(void *chunk, size_t size, ChunkType type) { @@ -2193,10 +2181,16 @@ chunk_dealloc(void *chunk, size_t size, ChunkType type) malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, nullptr); - if (chunk_dalloc_mmap(chunk, size)) + if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) { chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size, type); + return; + } + + pages_unmap(chunk, size); } +#undef CAN_RECYCLE + /* * End chunk management functions. */ From fda40761ff81d80ff0e2281e46101eb3176a333e Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 10 Aug 2017 09:22:55 +0900 Subject: [PATCH 145/166] Bug 1388935 - Avoid overflowing the chunk recycling limit with very large chunks. r=njn When recycling chunks, mozjemalloc tries to avoid keeping around more than 128MB worth of chunks around, but it doesn't actually look at the size of the chunks that are recycled, so if chunk larger than 128MB is recycled, it is kept as a whole, going well over the limit. The chunks are still properly reused, and further recycling doesn't occur, but that can limit other mmap users from getting enough address space. With this change, mozjemalloc now doesn't keep more than 128MB, by splitting the chunks it recycles if they are too large. Note this was not a problem on Windows, where chunks larger than 1MB are never recycled (per CAN_RECYCLE). --HG-- extra : rebase_source : 6765fd30b78ca5ddc7d55aac861355d960e47828 --- memory/mozjemalloc/mozjemalloc.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/memory/mozjemalloc/mozjemalloc.cpp b/memory/mozjemalloc/mozjemalloc.cpp index 005afbf0bd47..df4a1ce58020 100644 --- a/memory/mozjemalloc/mozjemalloc.cpp +++ b/memory/mozjemalloc/mozjemalloc.cpp @@ -140,6 +140,7 @@ #include #include #include +#include #ifdef MOZ_MEMORY_WINDOWS @@ -148,7 +149,6 @@ #include #include #include -#include #define SIZE_T_MAX SIZE_MAX #define STDERR_FILENO 2 @@ -2181,9 +2181,22 @@ chunk_dealloc(void *chunk, size_t size, ChunkType type) malloc_rtree_set(chunk_rtree, (uintptr_t)chunk, nullptr); - if (CAN_RECYCLE(size) && load_acquire_z(&recycled_size) < recycle_limit) { - chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size, type); - return; + if (CAN_RECYCLE(size)) { + size_t recycled_so_far = load_acquire_z(&recycled_size); + // In case some race condition put us above the limit. + if (recycled_so_far < recycle_limit) { + size_t recycle_remaining = recycle_limit - recycled_so_far; + size_t to_recycle; + if (size > recycle_remaining) { + to_recycle = recycle_remaining; + // Drop pages that would overflow the recycle limit + pages_trim(chunk, size, 0, to_recycle); + } else { + to_recycle = size; + } + chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, to_recycle, type); + return; + } } pages_unmap(chunk, size); From a3a73bd46c03d48c389b9df5c3621cd00facc0b8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 10 Aug 2017 00:04:28 -0500 Subject: [PATCH 146/166] servo: Merge #18032 - stylo: Fixes for min font size and logical properties (from Manishearth:fixes); r=heycam r=heycam https://bugzilla.mozilla.org/show_bug.cgi?id=1388941 and https://bugzilla.mozilla.org/show_bug.cgi?id=1388943 Source-Repo: https://github.com/servo/servo Source-Revision: d415617a5bbe65a73bd805808a7ac76f38a1861c --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : f202098a1671114b6ab90617eae604bee2b7883f --- .../components/style/properties/gecko.mako.rs | 7 +++--- servo/components/style/rule_tree/mod.rs | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 186627be1104..7785e8aa47a1 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -2643,12 +2643,13 @@ fn static_assert() { #[allow(non_snake_case)] pub fn set__moz_min_font_size_ratio(&mut self, v: longhands::_moz_min_font_size_ratio::computed_value::T) { - let percentage = if v.0 > 255. { + let scaled = v.0 * 100.; + let percentage = if scaled > 255. { 255. - } else if v.0 < 0. { + } else if scaled < 0. { 0. } else { - v.0 + scaled }; self.gecko.mMinFontSizeRatio = percentage as u8; diff --git a/servo/components/style/rule_tree/mod.rs b/servo/components/style/rule_tree/mod.rs index bcfe15604578..ff511a2a5832 100644 --- a/servo/components/style/rule_tree/mod.rs +++ b/servo/components/style/rule_tree/mod.rs @@ -1080,6 +1080,19 @@ impl StrongRuleNode { LonghandId::BorderTopRightRadius, LonghandId::BorderBottomRightRadius, LonghandId::BorderBottomLeftRadius, + + LonghandId::BorderInlineStartColor, + LonghandId::BorderInlineStartStyle, + LonghandId::BorderInlineStartWidth, + LonghandId::BorderInlineEndColor, + LonghandId::BorderInlineEndStyle, + LonghandId::BorderInlineEndWidth, + LonghandId::BorderBlockStartColor, + LonghandId::BorderBlockStartStyle, + LonghandId::BorderBlockStartWidth, + LonghandId::BorderBlockEndColor, + LonghandId::BorderBlockEndStyle, + LonghandId::BorderBlockEndWidth, ]; const PADDING_PROPS: &'static [LonghandId] = &[ @@ -1087,6 +1100,11 @@ impl StrongRuleNode { LonghandId::PaddingRight, LonghandId::PaddingBottom, LonghandId::PaddingLeft, + + LonghandId::PaddingInlineStart, + LonghandId::PaddingInlineEnd, + LonghandId::PaddingBlockStart, + LonghandId::PaddingBlockEnd, ]; // Inherited properties: @@ -1131,6 +1149,10 @@ impl StrongRuleNode { LonghandId::BorderRightColor, LonghandId::BorderBottomColor, LonghandId::BorderLeftColor, + LonghandId::BorderInlineStartColor, + LonghandId::BorderInlineEndColor, + LonghandId::BorderBlockStartColor, + LonghandId::BorderBlockEndColor, LonghandId::TextShadow, ]; From e6931eca1a14bac08a4e0ee1a6b2077417303295 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 9 Aug 2017 17:21:59 -0700 Subject: [PATCH 147/166] Bug 1388941 - Remove unnecessary fails(stylo) annotation from fuzzy test; r=heycam MozReview-Commit-ID: ERUIHRQwXc7 --- layout/reftests/w3c-css/received/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/w3c-css/received/reftest.list b/layout/reftests/w3c-css/received/reftest.list index 8fb03e5853a1..128d1fcf8121 100644 --- a/layout/reftests/w3c-css/received/reftest.list +++ b/layout/reftests/w3c-css/received/reftest.list @@ -1080,7 +1080,7 @@ fuzzy-if(OSX,15,16) == css-writing-modes-3/text-combine-upright-decorations-001. == css-writing-modes-3/text-combine-upright-inherit-all-002.html css-writing-modes-3/reference/text-combine-upright-inherit-all-002.html == css-writing-modes-3/text-combine-upright-layout-rules-001.html css-writing-modes-3/reference/text-combine-upright-layout-rules-001-ref.html == css-writing-modes-3/text-combine-upright-line-breaking-rules-001.html css-writing-modes-3/text-combine-upright-line-breaking-rules-001-ref.html -fuzzy(255,960) fails-if(stylo) == css-writing-modes-3/text-combine-upright-value-all-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html +fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-001.html css-writing-modes-3/reference/text-combine-upright-value-single-character.html fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html fuzzy(255,960) != css-writing-modes-3/text-combine-upright-value-all-002.html css-writing-modes-3/reference/horizontal-ahem-1x1-notref.html fuzzy(255,960) == css-writing-modes-3/text-combine-upright-value-all-003.html css-writing-modes-3/reference/vertical-ahem-1x1-ref.html From 4af3a23604312d328a9292c9b1b2074783e6e464 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 9 Aug 2017 18:20:08 -0700 Subject: [PATCH 148/166] Bug 1388941 - Correctly scale -moz-min-font-size-ratio ; r=heycam MozReview-Commit-ID: KoKFXzSdakU --- layout/reftests/css-ruby/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/css-ruby/reftest.list b/layout/reftests/css-ruby/reftest.list index e6d712c72111..1a9366dad130 100644 --- a/layout/reftests/css-ruby/reftest.list +++ b/layout/reftests/css-ruby/reftest.list @@ -36,7 +36,7 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),3,2) == line-break-suppressi == line-height-2.html line-height-2-ref.html == line-height-3.html line-height-3-ref.html == line-height-4.html line-height-4-ref.html -test-pref(font.minimum-size.ja,16) fails-if(styloVsGecko||stylo) == min-font-size-1.html min-font-size-1-ref.html +test-pref(font.minimum-size.ja,16) == min-font-size-1.html min-font-size-1-ref.html load nested-ruby-1.html == no-transform.html no-transform-ref.html == relative-positioning-1.html relative-positioning-1-ref.html From 6f0180e2cb5fdb0e59384cc8abd58f2e5ced8c75 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 9 Aug 2017 18:39:47 -0700 Subject: [PATCH 149/166] Bug 1388943 - Include logical properties in has_author_specified_rules ; r=heycam MozReview-Commit-ID: 6l2ZqLZwkZJ --- layout/reftests/native-theme/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/native-theme/reftest.list b/layout/reftests/native-theme/reftest.list index 7c9651c5da99..590327fc4636 100644 --- a/layout/reftests/native-theme/reftest.list +++ b/layout/reftests/native-theme/reftest.list @@ -12,7 +12,7 @@ # The following tests will fail if the platform does not have native # theme support (which all platforms should have). fails-if(!nativeThemePref) != text-input-native.html text-input-nonnative.html -fuzzy-if(skiaContent,2,88) fails-if(styloVsGecko||stylo) == text-input-nonnative-when-styled.html text-input-nonnative-when-styled-ref.html +fuzzy-if(skiaContent,2,88) == text-input-nonnative-when-styled.html text-input-nonnative-when-styled-ref.html fails-if(!nativeThemePref) != textarea-native.html textarea-nonnative.html fuzzy-if(skiaContent,2,53) == textarea-nonnative-when-styled.html textarea-nonnative-when-styled-ref.html fails-if(!nativeThemePref) != button-native.html button-nonnative.html From ac234bd18b36cbcf936c8701c20994dad3e1537c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 10 Aug 2017 07:37:47 +0200 Subject: [PATCH 150/166] Bug 1386964 - Set default tab height, mark flaky viewport-units-css2-001.html subtests as passing on Linux as well as anchoring-with-bounds-clamping.html on Mac. r=dholbert MozReview-Commit-ID: 2gNQSImPfw1 --HG-- extra : rebase_source : d9c78ddbc9196f5f9975e78cc7715b0adb8b4b1a --- browser/themes/shared/tabs.inc.css | 2 -- .../meta/css/css-values-3/viewport-units-css2-001.html.ini | 6 ++++-- .../anchoring-with-bounds-clamping.html.ini | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index 2dc39d514952..c26c806f5ef8 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -6,12 +6,10 @@ :root { --tab-toolbar-navbar-overlap: 1px; -/* Temporarily using the compact tab strip by default because of bug 1386964: --tab-min-height: 33px; } :root[uidensity=compact] { -*/ --tab-min-height: 29px; } diff --git a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini index eed6261f7ab0..5f8aad9ff46c 100644 --- a/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini +++ b/testing/web-platform/meta/css/css-values-3/viewport-units-css2-001.html.ini @@ -7,10 +7,12 @@ if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL [vh length applied to border-top-width] - expected: FAIL + expected: + if os != "linux": FAIL [vmin length applied to border-top-width] - expected: FAIL + expected: + if os != "linux": FAIL [vmax length applied to border-top-width] expected: diff --git a/testing/web-platform/meta/scroll-anchoring/anchoring-with-bounds-clamping.html.ini b/testing/web-platform/meta/scroll-anchoring/anchoring-with-bounds-clamping.html.ini index d1c61a84cc2e..d048ab44fe38 100644 --- a/testing/web-platform/meta/scroll-anchoring/anchoring-with-bounds-clamping.html.ini +++ b/testing/web-platform/meta/scroll-anchoring/anchoring-with-bounds-clamping.html.ini @@ -1,5 +1,6 @@ [anchoring-with-bounds-clamping.html] type: testharness [Anchoring combined with scroll bounds clamping in the document.] - expected: FAIL + expected: + if os != "mac": FAIL From 4418d7d98601c18cac54b1d549b5d959317f0db7 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 18 Jul 2017 16:54:31 +0900 Subject: [PATCH 151/166] Bug 1381710 - Selection.addRange will be failure with dynamic table insertion. r=tnikkel When range is selected table element, Selection.addRange uses nsFrameSelection. If frame isn't constructed yet, addRange throws NS_ERROR_FAILURE even if table element isn't editable element. When getting nsITableCellLayout, we should flush frame to construct cell frame. MozReview-Commit-ID: 9qWwW46RYNL --HG-- extra : rebase_source : 708e78af457a28bc273b83015f78950a5bee232e --- dom/base/Selection.cpp | 19 +++++++++++--- dom/base/test/mochitest.ini | 1 + dom/base/test/test_bug1381710.html | 40 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 dom/base/test/test_bug1381710.html diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index 25de5dfc6f9c..7c807a6bcc2d 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -605,14 +605,24 @@ Selection::GetTableCellLocationFromRange(nsRange* aRange, if (!content) return NS_ERROR_FAILURE; - nsIContent *child = content->GetChildAt(aRange->StartOffset()); + nsCOMPtr child = content->GetChildAt(aRange->StartOffset()); if (!child) return NS_ERROR_FAILURE; + // GetCellLayout depends on current frame, we need flush frame to get + // nsITableCellLayout + nsCOMPtr presShell = mFrameSelection->GetShell(); + if (presShell) { + presShell->FlushPendingNotifications(FlushType::Frames); + + // Since calling FlushPendingNotifications, so check whether disconnected. + if (!mFrameSelection || !mFrameSelection->GetShell()) { + return NS_ERROR_FAILURE; + } + } + //Note: This is a non-ref-counted pointer to the frame nsITableCellLayout *cellLayout = mFrameSelection->GetCellLayout(child); - if (NS_FAILED(result)) - return result; if (!cellLayout) return NS_ERROR_FAILURE; @@ -2276,6 +2286,9 @@ Selection::AddRangeInternal(nsRange& aRange, nsIDocument* aDocument, return; } + // AddTableCellRange might flush frame. + RefPtr kungFuDeathGrip(this); + // This inserts a table cell range in proper document order // and returns NS_OK if range doesn't contain just one table cell bool didAddRange; diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 656e6f84eb34..ed108ab1b139 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -621,6 +621,7 @@ skip-if = toolkit == 'android' [test_bug1314032.html] [test_bug1318303.html] [test_bug1375050.html] +[test_bug1381710.html] [test_bug1384658.html] skip-if = toolkit == 'android' [test_caretPositionFromPoint.html] diff --git a/dom/base/test/test_bug1381710.html b/dom/base/test/test_bug1381710.html new file mode 100644 index 000000000000..f8bec87705c5 --- /dev/null +++ b/dom/base/test/test_bug1381710.html @@ -0,0 +1,40 @@ + + + + + Test for Mozilla Bug 1381710 + + + + +Mozilla Bug 1381710 +
+
+
+
+
+
+
+ + From db963af2af520fed8b06ac35fbf64f9f26864014 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 4 Aug 2017 14:27:14 +0200 Subject: [PATCH 152/166] bug 1320656 - Disable the failure on -Wnoexcept-type until we have a proper fix r=glandium MozReview-Commit-ID: HeDMTxopx9V --HG-- extra : rebase_source : 8df61de8f024bab38909826ca714e554c4b0bb49 --- js/src/moz.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/src/moz.build b/js/src/moz.build index e106ef7b214c..adb482be74ca 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -734,7 +734,10 @@ if CONFIG['JS_HAS_CTYPES']: if CONFIG['GNU_CXX']: # Also disable strict-aliasing for GCC compiler, that is enabled by default # starting with version 7.1, see Bug 1363009 - CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing'] + # Disable the gcc warning noexcept-type introduced in version 7.1. + # see bug 1320656 + CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing', + '-Wno-error=noexcept-type'] # Suppress warnings in third-party code. if CONFIG['CLANG_CXX'] or CONFIG['GNU_CXX']: From 683c18635011a44dfa2b70cdda9cdef4542b2bf1 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 10 Aug 2017 01:42:30 -0500 Subject: [PATCH 153/166] servo: Merge #18033 - Use namespace id instead of atom in synthesize_presentational_hints_for_legacy_attributes (from upsuper:disable-mathml); r=Manishearth Using namespace id fixes this issue because in Gecko, the pref of MathML (as well as SVG) works in the way that we choose a different namespace id (the disabled id) for the elements. Those ids are mapped to the same namespace atom as normal ids, which means if we use the atom, we would treat the elements like normal mathml elements. https://bugzilla.mozilla.org/show_bug.cgi?id=1388881 Source-Repo: https://github.com/servo/servo Source-Revision: 1877cac477770c5908f4b9983adaf7108a361e6e --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 5be2c9ddb0f8745f4c7e4f8905949800f4b63e76 --- servo/components/style/gecko/wrapper.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index b3cd83ea3dfb..0ecbf8abe7bc 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -1534,9 +1534,9 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> { }; }; - let ns = self.get_namespace(); + let ns = self.namespace_id(); // elements get a default MozCenterOrInherit which may get overridden - if ns == &*Namespace(atom!("http://www.w3.org/1999/xhtml")) { + if ns == structs::kNameSpaceID_XHTML as i32 { if self.get_local_name().as_ptr() == atom!("th").as_ptr() { hints.push(TH_RULE.clone()); } else if self.get_local_name().as_ptr() == atom!("table").as_ptr() && @@ -1544,7 +1544,7 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> { hints.push(TABLE_COLOR_RULE.clone()); } } - if ns == &*Namespace(atom!("http://www.w3.org/2000/svg")) { + if ns == structs::kNameSpaceID_SVG as i32 { if self.get_local_name().as_ptr() == atom!("text").as_ptr() { hints.push(SVG_TEXT_DISABLE_ZOOM_RULE.clone()); } @@ -1621,7 +1621,7 @@ impl<'le> PresentationalHintsSynthesizer for GeckoElement<'le> { hints.push(ApplicableDeclarationBlock::from_declarations(arc, ServoCascadeLevel::PresHints)) } // MathML's default lang has precedence over both `lang` and `xml:lang` - if ns == &*Namespace(atom!("http://www.w3.org/1998/Math/MathML")) { + if ns == structs::kNameSpaceID_MathML as i32 { if self.get_local_name().as_ptr() == atom!("math").as_ptr() { hints.push(MATHML_LANG_RULE.clone()); } From c0203dbf2c5de29e53d7cab296ec67b48324d4ae Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 10 Aug 2017 16:29:17 +1000 Subject: [PATCH 154/166] Bug 1388881 - Use namespace id instead of atom in synthesize_presentational_hints_for_legacy_attributes. r=manishearth Using namespace id fixes this issue because in Gecko, the pref of MathML (as well as SVG) works in the way that we choose a different namespace id (the disabled id) for the elements. Those ids are mapped to the same namespace atom as normal ids, which means if we use the atom, we would treat the elements like normal mathml elements. MozReview-Commit-ID: 9YBBokbP04M --HG-- extra : rebase_source : 397f09db41a22bfa34e4abe26ad10027dab83d0d --- layout/reftests/mathml/reftest.list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/reftests/mathml/reftest.list b/layout/reftests/mathml/reftest.list index 6a779b14d0c8..b4a69616cc23 100644 --- a/layout/reftests/mathml/reftest.list +++ b/layout/reftests/mathml/reftest.list @@ -11,8 +11,8 @@ fails-if(!styloVsGecko) == dir-9.html dir-9-ref.html # Bug 787215 == dir-10.html dir-10-ref.html == dir-11.html dir-11-ref.html == css-spacing-1.html css-spacing-1-ref.html -pref(mathml.disabled,true) fails-if(styloVsGecko||stylo) == disabled-scriptlevel-1.html disabled-scriptlevel-1-ref.html -pref(mathml.disabled,true) fails-if(styloVsGecko||stylo) == disabled-scriptlevel-1.xhtml disabled-scriptlevel-1-ref.xhtml +pref(mathml.disabled,true) == disabled-scriptlevel-1.html disabled-scriptlevel-1-ref.html +pref(mathml.disabled,true) == disabled-scriptlevel-1.xhtml disabled-scriptlevel-1-ref.xhtml == displaystyle-1.html displaystyle-1-ref.html == displaystyle-2.html displaystyle-2-ref.html == displaystyle-3.html displaystyle-3-ref.html From b287601ebcdf3f406599242c3e52c153f09246ad Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 10:21:56 +0200 Subject: [PATCH 155/166] Backed out changeset 61cf451831f5 (bug 1320656) for bustage in RegExp.o. r=backout on a CLOSED TREE --- js/src/moz.build | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/js/src/moz.build b/js/src/moz.build index adb482be74ca..e106ef7b214c 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -734,10 +734,7 @@ if CONFIG['JS_HAS_CTYPES']: if CONFIG['GNU_CXX']: # Also disable strict-aliasing for GCC compiler, that is enabled by default # starting with version 7.1, see Bug 1363009 - # Disable the gcc warning noexcept-type introduced in version 7.1. - # see bug 1320656 - CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing', - '-Wno-error=noexcept-type'] + CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing'] # Suppress warnings in third-party code. if CONFIG['CLANG_CXX'] or CONFIG['GNU_CXX']: From 6a474244a887461b8f9cc796d5b1cb243dbc3264 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 10:23:22 +0200 Subject: [PATCH 156/166] Backed out changeset 78d87b59f5a7 (bug 1370508) for unexpected pass of wpt-reftest /css/css-namespaces-3/syntax-013.xml. r=backout on a CLOSED TREE --- dom/base/nsDocument.cpp | 3 ++- layout/reftests/w3c-css/failures.list | 4 ---- layout/reftests/w3c-css/received/reftest.list | 2 +- layout/xul/crashtests/crashtests.list | 2 +- .../web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini | 3 --- 5 files changed, 4 insertions(+), 10 deletions(-) delete mode 100644 testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 0f3fd562c77f..b4773160af92 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -13224,7 +13224,8 @@ nsIDocument::UpdateStyleBackendType() mStyleBackendType = StyleBackendType::Servo; } else if (!mDocumentContainer) { NS_WARNING("stylo: No docshell yet, assuming Gecko style system"); - } else if (!IsXULDocument() && IsContentDocument()) { + } else if ((IsHTMLOrXHTML() || IsSVGDocument()) && + IsContentDocument()) { // Disable stylo for about: pages other than about:blank, since // they tend to use unsupported selectors like XUL tree pseudos. bool isAbout = false; diff --git a/layout/reftests/w3c-css/failures.list b/layout/reftests/w3c-css/failures.list index 1560f4ad673d..966f69ff9ae0 100644 --- a/layout/reftests/w3c-css/failures.list +++ b/layout/reftests/w3c-css/failures.list @@ -314,7 +314,3 @@ fuzzy(255,2808) css-multicol-1/multicol-rule-large-001.xht fails-if(!styloVsGecko) css-multicol-1/multicol-fill-auto-block-children-001.xht fails-if(!styloVsGecko) css-multicol-1/multicol-fill-auto-block-children-002.xht fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-block-sibling-003.xht - -#### CSS Namespaces 3 ############################################## - -fails-if(stylo||styloVsGecko) css-namespaces-3/syntax-013.xml diff --git a/layout/reftests/w3c-css/received/reftest.list b/layout/reftests/w3c-css/received/reftest.list index 128d1fcf8121..eb6151266acd 100644 --- a/layout/reftests/w3c-css/received/reftest.list +++ b/layout/reftests/w3c-css/received/reftest.list @@ -205,7 +205,7 @@ fails-if(!styloVsGecko) == css-multicol-1/multicol-zero-height-001.xht css-multi == css-namespaces-3/syntax-010.xml css-namespaces-3/reftest/ref-lime-3.xml == css-namespaces-3/syntax-011.xml css-namespaces-3/reftest/ref-lime-6.xml == css-namespaces-3/syntax-012.xml css-namespaces-3/reftest/ref-lime-3.xml -fails-if(stylo||styloVsGecko) == css-namespaces-3/syntax-013.xml css-namespaces-3/reftest/ref-lime-5.xml # bug 1388911 +== css-namespaces-3/syntax-013.xml css-namespaces-3/reftest/ref-lime-5.xml == css-namespaces-3/syntax-014.xml css-namespaces-3/reftest/ref-lime-3.xml == css-namespaces-3/syntax-015.xml css-namespaces-3/reftest/ref-lime-1.xml fails-if(!styloVsGecko) == css-values-3/attr-color-invalid-cast.html css-values-3/reference/200-200-green.html diff --git a/layout/xul/crashtests/crashtests.list b/layout/xul/crashtests/crashtests.list index e60af3526383..c1445cb5ec7a 100644 --- a/layout/xul/crashtests/crashtests.list +++ b/layout/xul/crashtests/crashtests.list @@ -1,6 +1,6 @@ load 131008-1.xul load 137216-1.xul -asserts-if(stylo,3) load 140218-1.xml +load 140218-1.xml load 151826-1.xul load 168724-1.xul load 189814-1.xul diff --git a/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini b/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini deleted file mode 100644 index eb1f51d57bba..000000000000 --- a/testing/web-platform/meta/css/css-namespaces-3/syntax-013.xml.ini +++ /dev/null @@ -1,3 +0,0 @@ -[syntax-013.xml] - type: reftest - expected: FAIL From 7ed5c41a4c4ebbd0a82816676b8be1114ced9c69 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 10 Aug 2017 08:47:26 +0200 Subject: [PATCH 157/166] Bug 1388994 - GetRequestingPrincipal: Pass parameter by ref instead of value r=dragana MozReview-Commit-ID: 5iD8HF0PQfs --HG-- extra : rebase_source : 516bbfa30168779200fdca09033a5d1b3f1d884b --- netwerk/ipc/NeckoParent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 6dbfd8d66692..075adaf65c6f 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -110,7 +110,7 @@ PBOverrideStatusFromLoadContext(const SerializedLoadContext& aSerialized) } static already_AddRefed -GetRequestingPrincipal(const OptionalLoadInfoArgs aOptionalLoadInfoArgs) +GetRequestingPrincipal(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs) { if (aOptionalLoadInfoArgs.type() != OptionalLoadInfoArgs::TLoadInfoArgs) { return nullptr; From 756cf62ecabfefe7cfdb136cee8ed89957ee867c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 10 Aug 2017 09:34:34 +0200 Subject: [PATCH 158/166] Bug 1372839 - SkipString; Exit early if sym is not found r=gerald MozReview-Commit-ID: GnqPuW8FL5F --HG-- extra : rebase_source : b3c44c8daecc5341957d5953a525af82afba705a --- media/gmp-clearkey/0.1/ClearKeyUtils.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/media/gmp-clearkey/0.1/ClearKeyUtils.cpp b/media/gmp-clearkey/0.1/ClearKeyUtils.cpp index 0ed47671645d..a1a32e29dbe3 100644 --- a/media/gmp-clearkey/0.1/ClearKeyUtils.cpp +++ b/media/gmp-clearkey/0.1/ClearKeyUtils.cpp @@ -236,6 +236,9 @@ SkipString(ParserContext& aCtx) for (uint8_t sym = GetNextSymbol(aCtx); sym; sym = GetNextSymbol(aCtx)) { if (sym == '\\') { sym = GetNextSymbol(aCtx); + if (!sym) { + return false; + } } else if (sym == '"') { return true; } From 45fa0bdb26db237f40bfa9df060bc9b49246cb29 Mon Sep 17 00:00:00 2001 From: Gian-Carlo Pascutto Date: Wed, 9 Aug 2017 18:51:51 +0200 Subject: [PATCH 159/166] Bug 1388046 - Disable sandbox read restrictions (level 3) on beta/release. r=jld MozReview-Commit-ID: 3VQM545aqpL --HG-- extra : rebase_source : 75d2091dd3cb99027091247bfc90358e3cb8d440 --- browser/app/profile/firefox.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 4df1f64867f7..8ae2b0c20dc9 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1096,7 +1096,11 @@ pref("security.sandbox.content.level", 3); // // This setting may not be required anymore once we decide to permanently // enable the content sandbox. +#ifdef NIGHTLY_BUILD pref("security.sandbox.content.level", 3); +#else +pref("security.sandbox.content.level", 2); +#endif pref("security.sandbox.content.write_path_whitelist", ""); pref("security.sandbox.content.read_path_whitelist", ""); pref("security.sandbox.content.syscall_whitelist", ""); From b461ae5e9b2b50314b217e6eac174b936a367610 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 11:16:27 +0200 Subject: [PATCH 160/166] Backed out changeset f03833f24817 (bug 1024182) for heap buffer overflow at AudioNodeEngine.cpp:375:12 in mozilla::AudioBufferSumOfSquares. r=backout --- dom/media/webaudio/ConvolverNode.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index f81860cad23f..5cb67a0bdfff 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -272,6 +272,23 @@ ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv) uint32_t length = mBuffer->Length(); RefPtr data = mBuffer->GetThreadSharedChannelsForRate(aCx); + if (data && length < WEBAUDIO_BLOCK_SIZE) { + // For very small impulse response buffers, we need to pad the + // buffer with 0 to make sure that the Reverb implementation + // has enough data to compute FFTs from. + length = WEBAUDIO_BLOCK_SIZE; + RefPtr paddedBuffer = + new ThreadSharedFloatArrayBufferList(data->GetChannels()); + void* channelData = malloc(sizeof(float) * length * data->GetChannels() + 15); + float* alignedChannelData = ALIGNED16(channelData); + ASSERT_ALIGNED16(alignedChannelData); + for (uint32_t i = 0; i < data->GetChannels(); ++i) { + PodCopy(alignedChannelData + length * i, data->GetData(i), mBuffer->Length()); + PodZero(alignedChannelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length()); + paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, alignedChannelData); + } + data = paddedBuffer; + } SendInt32ParameterToStream(ConvolverNodeEngine::BUFFER_LENGTH, length); SendDoubleParameterToStream(ConvolverNodeEngine::SAMPLE_RATE, mBuffer->SampleRate()); From 64aa1882b5f2b3da60b1a2094a34c57d9ab3bf66 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 11:17:07 +0200 Subject: [PATCH 161/166] Backed out changeset af73f36f7469 (bug 1388656) --- dom/media/webaudio/ConvolverNode.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 5cb67a0bdfff..045cd9680333 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -49,6 +49,7 @@ public: case BUFFER_LENGTH: // BUFFER_LENGTH is the first parameter that we set when setting a new buffer, // so we should be careful to invalidate the rest of our state here. + mBuffer = nullptr; mSampleRate = 0.0f; mBufferLength = aParam; mLeftOverData = INT32_MIN; @@ -74,7 +75,7 @@ public: } void SetBuffer(already_AddRefed aBuffer) override { - RefPtr buffer = aBuffer; + mBuffer = aBuffer; // Note about empirical tuning (this is copied from Blink) // The maximum FFT size affects reverb performance and accuracy. @@ -84,13 +85,13 @@ public: // Very large FFTs will have worse phase errors. Given these constraints 32768 is a good compromise. const size_t MaxFFTSize = 32768; - if (!buffer || !mBufferLength || !mSampleRate) { + if (!mBuffer || !mBufferLength || !mSampleRate) { mReverb = nullptr; mLeftOverData = INT32_MIN; return; } - mReverb = new WebCore::Reverb(buffer, mBufferLength, + mReverb = new WebCore::Reverb(mBuffer, mBufferLength, MaxFFTSize, mUseBackgroundThreads, mNormalize, mSampleRate); } @@ -158,6 +159,9 @@ public: size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override { size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf); + if (mBuffer && !mBuffer->IsShared()) { + amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf); + } if (mReverb) { amount += mReverb->sizeOfIncludingThis(aMallocSizeOf); @@ -172,6 +176,7 @@ public: } private: + RefPtr mBuffer; nsAutoPtr mReverb; int32_t mBufferLength; int32_t mLeftOverData; From 69e0a8b3f755efc4e95448ec30ae6fe52dd36ad8 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 11:17:13 +0200 Subject: [PATCH 162/166] Backed out changeset ece4f9694407 (bug 1388656) --- dom/media/webaudio/ConvolverNode.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 045cd9680333..7d80d7f8077d 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -66,8 +66,7 @@ public: switch (aIndex) { case SAMPLE_RATE: mSampleRate = aParam; - // The buffer is passed after the sample rate. - // mReverb will be set using this sample rate when the buffer is received. + AdjustReverb(); break; default: NS_ERROR("Bad ConvolverNodeEngine DoubleParameter"); @@ -76,7 +75,11 @@ public: void SetBuffer(already_AddRefed aBuffer) override { mBuffer = aBuffer; + AdjustReverb(); + } + void AdjustReverb() + { // Note about empirical tuning (this is copied from Blink) // The maximum FFT size affects reverb performance and accuracy. // If the reverb is single-threaded and processes entirely in the real-time audio thread, From 290327d0fb54b1bc08fc1c5dcaf97976b82142c1 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 11:17:18 +0200 Subject: [PATCH 163/166] Backed out changeset 1eb9ee70ccf1 (bug 1388656) --- dom/media/webaudio/ConvolverNode.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index 7d80d7f8077d..a137e3f2a371 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -54,6 +54,9 @@ public: mBufferLength = aParam; mLeftOverData = INT32_MIN; break; + case SAMPLE_RATE: + mSampleRate = aParam; + break; case NORMALIZE: mNormalize = !!aParam; break; From b0dd14223748c6ae015f053d0e8a81dc368b8d78 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 10 Aug 2017 11:18:36 +0200 Subject: [PATCH 164/166] Backed out changeset be8e60de5c0c (bug 1388656) for heap buffer overflow at AudioNodeEngine.cpp:375:12 in mozilla::AudioBufferSumOfSquares. r=backout --- dom/media/webaudio/ConvolverNode.cpp | 2 +- dom/media/webaudio/blink/Reverb.cpp | 8 ++++---- dom/media/webaudio/blink/Reverb.h | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/dom/media/webaudio/ConvolverNode.cpp b/dom/media/webaudio/ConvolverNode.cpp index a137e3f2a371..d257ff268a08 100644 --- a/dom/media/webaudio/ConvolverNode.cpp +++ b/dom/media/webaudio/ConvolverNode.cpp @@ -98,7 +98,7 @@ public: } mReverb = new WebCore::Reverb(mBuffer, mBufferLength, - MaxFFTSize, mUseBackgroundThreads, + MaxFFTSize, 2, mUseBackgroundThreads, mNormalize, mSampleRate); } diff --git a/dom/media/webaudio/blink/Reverb.cpp b/dom/media/webaudio/blink/Reverb.cpp index 6a5c04c45cda..4fca0822b6a8 100644 --- a/dom/media/webaudio/blink/Reverb.cpp +++ b/dom/media/webaudio/blink/Reverb.cpp @@ -77,7 +77,7 @@ static float calculateNormalizationScale(ThreadSharedFloatArrayBufferList* respo return scale; } -Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, bool useBackgroundThreads, bool normalize, float sampleRate) +Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize, float sampleRate) { float scale = 1; @@ -102,7 +102,7 @@ Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulse } initialize(irChannels, impulseResponseBufferLength, - maxFFTSize, useBackgroundThreads); + maxFFTSize, numberOfChannels, useBackgroundThreads); } size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const @@ -122,13 +122,13 @@ size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const void Reverb::initialize(const nsTArray& impulseResponseBuffer, size_t impulseResponseBufferLength, - size_t maxFFTSize, bool useBackgroundThreads) + size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads) { m_impulseResponseLength = impulseResponseBufferLength; // The reverb can handle a mono impulse response and still do stereo processing size_t numResponseChannels = impulseResponseBuffer.Length(); - m_convolvers.SetCapacity(numResponseChannels); + m_convolvers.SetCapacity(numberOfChannels); int convolverRenderPhase = 0; for (size_t i = 0; i < numResponseChannels; ++i) { diff --git a/dom/media/webaudio/blink/Reverb.h b/dom/media/webaudio/blink/Reverb.h index d8b054655983..35e72283dcde 100644 --- a/dom/media/webaudio/blink/Reverb.h +++ b/dom/media/webaudio/blink/Reverb.h @@ -50,7 +50,8 @@ public: // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread). Reverb(mozilla::ThreadSharedFloatArrayBufferList* impulseResponseBuffer, size_t impulseResponseBufferLength, size_t maxFFTSize, - bool useBackgroundThreads, bool normalize, float sampleRate); + size_t numberOfChannels, bool useBackgroundThreads, bool normalize, + float sampleRate); void process(const mozilla::AudioBlock* sourceBus, mozilla::AudioBlock* destinationBus); @@ -62,7 +63,7 @@ public: private: void initialize(const nsTArray& impulseResponseBuffer, size_t impulseResponseBufferLength, size_t maxFFTSize, - bool useBackgroundThreads); + size_t numberOfChannels, bool useBackgroundThreads); size_t m_impulseResponseLength; From ad74bc6fbca6d784c6620fbdfc2d68f246078d13 Mon Sep 17 00:00:00 2001 From: James Cheng Date: Thu, 10 Aug 2017 14:59:25 +0800 Subject: [PATCH 165/166] Bug 1388633 - Relax the duration constrain due to the duration may be changed in runtime. r=alwu The original duration I wrote is calculated from the m3u8 file this is too accurate without error tolerant. The state machine will update playback position periodically(UpdatePlaybackPositionPeriodically) according to the clockTime or max end time from A/Vsink. So the duration will be variant that I should consider to set the value to a more relaxed value. MozReview-Commit-ID: GGwkhvzz8sI --HG-- extra : rebase_source : c0465f7aef7a41e999e8c4c3429957fa56336239 --- dom/media/test/manifest.js | 2 +- dom/media/test/mochitest.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js index 478aaf87063c..515cfb3e9f76 100644 --- a/dom/media/test/manifest.js +++ b/dom/media/test/manifest.js @@ -27,7 +27,7 @@ function manifestVideo() { // name "mochi.test". let serverUrl = SpecialPowers.Services.prefs.getCharPref("media.hls.server.url"); var gHLSTests = [ - { name: serverUrl + "/bipbop_4x3_variant.m3u8", type:"audio/x-mpegurl", duration:19.95334 } + { name: serverUrl + "/bipbop_4x3_variant.m3u8", type:"audio/x-mpegurl", duration:20.000 } ]; // These are small test files, good for just seeing if something loads. We diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 27e13276d099..df20b61956f0 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -1213,7 +1213,7 @@ skip-if = (os == 'win' || android_version == '19') # bug 1374189 # HLS is only supported on Fennec with API level >= 16 # TODO: This test is similar to test_playback.html, will remove the # redundant code once test_playback.html is enabled on Fennec. -skip-if = toolkit != 'android' || android_version < '20' #bug 1388633 +skip-if = toolkit != 'android' || android_version < '16' tags = hls [test_hls_player_independency.html] From 5dcd453df27764c41f5a490b502cce878a9a1488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 10 Aug 2017 10:55:01 +0200 Subject: [PATCH 166/166] Bug 1389015 - Remove browser.inc. r=Gijs MozReview-Commit-ID: C1jFuu3fMLD --HG-- extra : rebase_source : a0583cbdd0122b35404e4f6aeb4f44384939a35f --- browser/themes/linux/browser.css | 2 -- browser/themes/osx/shared.inc | 1 - browser/themes/shared/browser.inc | 8 -------- browser/themes/shared/customizableui/panelUI.inc.css | 5 ++--- browser/themes/windows/browser-aero.css | 2 ++ browser/themes/windows/browser.css | 3 --- 6 files changed, 4 insertions(+), 17 deletions(-) delete mode 100644 browser/themes/shared/browser.inc diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css index 8714b18ff429..1b1e8b7d91aa 100644 --- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -10,8 +10,6 @@ @namespace html url("http://www.w3.org/1999/xhtml"); @namespace svg url("http://www.w3.org/2000/svg"); -%include ../shared/browser.inc - %include ../shared/browser.inc.css :root { diff --git a/browser/themes/osx/shared.inc b/browser/themes/osx/shared.inc index c0e3fa41e8c9..aacad914ca0e 100644 --- a/browser/themes/osx/shared.inc +++ b/browser/themes/osx/shared.inc @@ -1,5 +1,4 @@ %include ../../../toolkit/themes/osx/global/shared.inc -%include ../shared/browser.inc %filter substitution diff --git a/browser/themes/shared/browser.inc b/browser/themes/shared/browser.inc deleted file mode 100644 index e1556dbc4447..000000000000 --- a/browser/themes/shared/browser.inc +++ /dev/null @@ -1,8 +0,0 @@ -%filter substitution - -% Note that zoom-reset-button is a bit different since it doesn't use an image and thus has the image with display: none. -%define nestedButtons #zoom-out-button, #zoom-reset-button, #zoom-in-button, #cut-button, #copy-button, #paste-button - -%define inAnyPanel :-moz-any(:not([cui-areatype="toolbar"]), [overflowedItem=true]) - -%define panelPaletteIconSize var(--panel-palette-icon-size) \ No newline at end of file diff --git a/browser/themes/shared/customizableui/panelUI.inc.css b/browser/themes/shared/customizableui/panelUI.inc.css index aebef5362476..a4e47e9957ad 100644 --- a/browser/themes/shared/customizableui/panelUI.inc.css +++ b/browser/themes/shared/customizableui/panelUI.inc.css @@ -17,8 +17,8 @@ %define buttonStateActive :not([disabled]):-moz-any([open],:hover:active) %define menuStateActive :not([disabled])[_moz-menuactive]:active %define menuStateMenuActive :not([disabled])[_moz-menuactive] - -%include ../browser.inc +%define inAnyPanel :-moz-any(:not([cui-areatype="toolbar"]), [overflowedItem=true]) +%define panelPaletteIconSize 16px :root { --panel-ui-exit-subview-gutter-width: 38px; @@ -26,7 +26,6 @@ --appmenu-yellow-warning-color: #FFEFBF; --appmenu-yellow-warning-hover-color: #FFE8A2; --appmenu-yellow-warning-active-color: #FFE38F; - --panel-palette-icon-size: 16px; } #PanelUI-popup #PanelUI-contents:empty { diff --git a/browser/themes/windows/browser-aero.css b/browser/themes/windows/browser-aero.css index b2f03645c648..ade479ecf3ef 100644 --- a/browser/themes/windows/browser-aero.css +++ b/browser/themes/windows/browser-aero.css @@ -2,6 +2,8 @@ * 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/. */ +%filter substitution +%define toolbarShadowColor hsla(209,67%,12%,0.35) %define glassActiveBorderColor rgb(37, 44, 51) %define glassInactiveBorderColor rgb(102, 102, 102) diff --git a/browser/themes/windows/browser.css b/browser/themes/windows/browser.css index 6f0ffb2ad53c..402bf4955d27 100644 --- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -8,9 +8,6 @@ @namespace html url("http://www.w3.org/1999/xhtml"); @namespace svg url("http://www.w3.org/2000/svg"); -%include ../shared/browser.inc -%define toolbarShadowColor hsla(209,67%,12%,0.35) - %include ../shared/browser.inc.css :root {