diff options
author | Brian Birtles <birtles@gmail.com> | 2017-05-23 15:18:56 +0900 |
---|---|---|
committer | Brian Birtles <birtles@gmail.com> | 2017-05-24 11:08:51 +0900 |
commit | a408fd41dfa8a12c5e90318f4429475c5371d938 (patch) | |
tree | 14fd319565a9bb10121353eb63dc4b921395b9e0 | |
parent | 795d8ad76714cf2438608bcc543d0eb86a48ad0c (diff) | |
download | servo-a408fd41dfa8a12c5e90318f4429475c5371d938.tar.gz servo-a408fd41dfa8a12c5e90318f4429475c5371d938.zip |
Rework Servo_AnimationCompose to rely less on pinned temporaries
-rw-r--r-- | ports/geckolib/glue.rs | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index b3004a263f8..883524c7199 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -366,46 +366,61 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa return; } - // Temporaries used in the following if-block whose lifetimes we need to prolong. + // Extract keyframe values. let raw_from_value; - let from_composite_result; - let from_value = if !segment.mFromValue.mServo.mRawPtr.is_null() { + let keyframe_from_value = if !segment.mFromValue.mServo.mRawPtr.is_null() { raw_from_value = unsafe { &*segment.mFromValue.mServo.mRawPtr }; - match segment.mFromComposite { - CompositeOperation::Add | CompositeOperation::Accumulate => { - let value_to_composite = AnimationValue::as_arc(&raw_from_value).as_ref(); - from_composite_result = if segment.mFromComposite == CompositeOperation::Add { - underlying_value.as_ref().unwrap().add(value_to_composite) - } else { - underlying_value.as_ref().unwrap().accumulate(value_to_composite, 1) - }; - from_composite_result.as_ref().unwrap_or(value_to_composite) - } - _ => { AnimationValue::as_arc(&raw_from_value) } - } + Some(AnimationValue::as_arc(&raw_from_value)) } else { - underlying_value.as_ref().unwrap() + None }; let raw_to_value; - let to_composite_result; - let to_value = if !segment.mToValue.mServo.mRawPtr.is_null() { + let keyframe_to_value = if !segment.mToValue.mServo.mRawPtr.is_null() { raw_to_value = unsafe { &*segment.mToValue.mServo.mRawPtr }; - match segment.mToComposite { - CompositeOperation::Add | CompositeOperation::Accumulate => { - let value_to_composite = AnimationValue::as_arc(&raw_to_value).as_ref(); - to_composite_result = if segment.mToComposite == CompositeOperation::Add { - underlying_value.as_ref().unwrap().add(value_to_composite) - } else { - underlying_value.as_ref().unwrap().accumulate(value_to_composite, 1) - }; - to_composite_result.as_ref().unwrap_or(value_to_composite) - } - _ => { AnimationValue::as_arc(&raw_to_value) } - } + Some(AnimationValue::as_arc(&raw_to_value)) } else { - underlying_value.as_ref().unwrap() + None + }; + + // Composite with underlying value. + // A return value of None means, "Just use keyframe_value as-is." + let composite_endpoint = |keyframe_value: Option<&Arc<AnimationValue>>, + composite_op: CompositeOperation| -> Option<AnimationValue> { + match keyframe_value { + Some(keyframe_value) => { + match composite_op { + CompositeOperation::Add => { + debug_assert!(need_underlying_value, + "Should have detected we need an underlying value"); + underlying_value.as_ref().unwrap().add(keyframe_value).ok() + }, + CompositeOperation::Accumulate => { + debug_assert!(need_underlying_value, + "Should have detected we need an underlying value"); + underlying_value.as_ref().unwrap().accumulate(keyframe_value, 1).ok() + }, + _ => None, + } + }, + None => { + debug_assert!(need_underlying_value, + "Should have detected we need an underlying value"); + underlying_value.clone() + }, + } }; + let composited_from_value = composite_endpoint(keyframe_from_value, segment.mFromComposite); + let composited_to_value = composite_endpoint(keyframe_to_value, segment.mToComposite); + + debug_assert!(keyframe_from_value.is_some() || composited_from_value.is_some(), + "Should have a suitable from value to use"); + debug_assert!(keyframe_to_value.is_some() || composited_to_value.is_some(), + "Should have a suitable to value to use"); + + // Use the composited value if there is one, otherwise, use the original keyframe value. + let from_value = composited_from_value.as_ref().unwrap_or_else(|| keyframe_from_value.unwrap()); + let to_value = composited_to_value.as_ref().unwrap_or_else(|| keyframe_to_value.unwrap()); let progress = unsafe { Gecko_GetProgressFromComputedTiming(computed_timing) }; if segment.mToKey == segment.mFromKey { |