@@ -116,9 +116,9 @@ MultiFrameCodec::State::GetNextFrameImage(
116116 std::optional<unsigned int > prior_frame_index = std::nullopt ;
117117
118118 if (requiredFrameIndex != SkCodec::kNoFrame ) {
119- // We currently assume that frames can only ever depend on the immediately
120- // previous frame, if any. This means that
121- // `DisposalMethod::kRestorePrevious` is not supported .
119+ // We are here when the frame said |disposal_method| is
120+ // `DisposalMethod::kKeep` or `DisposalMethod::kRestorePrevious` and
121+ // |requiredFrameIndex| is set to ex-frame or ex-ex-frame .
122122 if (lastRequiredFrame_ == nullptr ) {
123123 FML_DLOG (INFO)
124124 << " Frame " << nextFrameIndex_ << " depends on frame "
@@ -146,9 +146,27 @@ MultiFrameCodec::State::GetNextFrameImage(
146146 return std::make_pair (nullptr , decode_error);
147147 }
148148
149- // Hold onto this if we need it to decode future frames.
150- if (frameInfo.disposal_method == SkCodecAnimation::DisposalMethod::kKeep ||
151- lastRequiredFrame_) {
149+ const bool keep_current_frame =
150+ frameInfo.disposal_method == SkCodecAnimation::DisposalMethod::kKeep ;
151+ const bool restore_previous_frame =
152+ frameInfo.disposal_method ==
153+ SkCodecAnimation::DisposalMethod::kRestorePrevious ;
154+ const bool previous_frame_available = !!lastRequiredFrame_;
155+
156+ // Store the current frame in `lastRequiredFrame_` if the frame's disposal
157+ // method indicates we should do so.
158+ // * When the disposal method is "Keep", the stored frame should always be
159+ // overwritten with the new frame we just crafted.
160+ // * When the disposal method is "RestorePrevious", the previously stored
161+ // frame should be retained and used as the backdrop for the next frame
162+ // again. If there isn't already a stored frame, that means we haven't
163+ // rendered any frames yet! When this happens, we just fall back to "Keep"
164+ // behavior and store the current frame as the backdrop of the next frame.
165+
166+ if (keep_current_frame ||
167+ (previous_frame_available && !restore_previous_frame)) {
168+ // Replace the stored frame. The `lastRequiredFrame_` will get used as the
169+ // starting backdrop for the next frame.
152170 lastRequiredFrame_ = std::make_unique<SkBitmap>(bitmap);
153171 lastRequiredFrameIndex_ = nextFrameIndex_;
154172 }
0 commit comments