mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Issue #2073 - m-c 1343341: Infrastructure necessary to allow discarding of animated images (squashed)
Includes squashed changes of: - m-c 1317907: Refactor FrameAnimator::GetCompositedFrame to be a bit simpler - m-c 1351434: bugfix - m-c 686905: Enable the pref image.mem.animated.discardable to allow discarding of animated images
This commit is contained in:
parent
7d75c2717f
commit
eac8afce35
14 changed files with 368 additions and 96 deletions
|
|
@ -174,7 +174,7 @@ RasterImage::RequestRefresh(const TimeStamp& aTime)
|
|||
RefreshResult res;
|
||||
if (mAnimationState) {
|
||||
MOZ_ASSERT(mFrameAnimator);
|
||||
res = mFrameAnimator->RequestRefresh(*mAnimationState, aTime);
|
||||
res = mFrameAnimator->RequestRefresh(*mAnimationState, aTime, mAnimationFinished);
|
||||
}
|
||||
|
||||
if (res.mFrameAdvanced) {
|
||||
|
|
@ -275,8 +275,7 @@ RasterImage::LookupFrameInternal(const IntSize& aSize,
|
|||
MOZ_ASSERT(mFrameAnimator);
|
||||
MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
|
||||
"Can't composite frames with non-default surface flags");
|
||||
const size_t index = mAnimationState->GetCurrentAnimationFrameIndex();
|
||||
return mFrameAnimator->GetCompositedFrame(index);
|
||||
return mFrameAnimator->GetCompositedFrame(*mAnimationState);
|
||||
}
|
||||
|
||||
SurfaceFlags surfaceFlags = ToSurfaceFlags(aFlags);
|
||||
|
|
@ -332,6 +331,7 @@ RasterImage::LookupFrame(const IntSize& aSize,
|
|||
// one. (Or we're sync decoding and the existing decoder hasn't even started
|
||||
// yet.) Trigger decoding so it'll be available next time.
|
||||
MOZ_ASSERT(aPlaybackType != PlaybackType::eAnimated ||
|
||||
gfxPrefs::ImageMemAnimatedDiscardable() ||
|
||||
!mAnimationState || mAnimationState->KnownFrameCount() < 1,
|
||||
"Animated frames should be locked");
|
||||
|
||||
|
|
@ -399,7 +399,7 @@ RasterImage::WillDrawOpaqueNow()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mAnimationState) {
|
||||
if (mAnimationState && !gfxPrefs::ImageMemAnimatedDiscardable()) {
|
||||
// We never discard frames of animated images.
|
||||
return true;
|
||||
}
|
||||
|
|
@ -426,11 +426,33 @@ RasterImage::WillDrawOpaqueNow()
|
|||
}
|
||||
|
||||
void
|
||||
RasterImage::OnSurfaceDiscarded()
|
||||
RasterImage::OnSurfaceDiscarded(const SurfaceKey& aSurfaceKey)
|
||||
{
|
||||
MOZ_ASSERT(mProgressTracker);
|
||||
|
||||
NS_DispatchToMainThread(NewRunnableMethod(mProgressTracker, &ProgressTracker::OnDiscard));
|
||||
bool animatedFramesDiscarded =
|
||||
mAnimationState && aSurfaceKey.Playback() == PlaybackType::eAnimated;
|
||||
|
||||
RefPtr<RasterImage> image = this;
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
[=]() -> void {
|
||||
image->OnSurfaceDiscardedInternal(animatedFramesDiscarded);
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aAnimatedFramesDiscarded && mAnimationState) {
|
||||
MOZ_ASSERT(gfxPrefs::ImageMemAnimatedDiscardable());
|
||||
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
|
||||
}
|
||||
|
||||
if (mProgressTracker) {
|
||||
mProgressTracker->OnDiscard();
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
|
@ -706,9 +728,11 @@ RasterImage::SetMetadata(const ImageMetadata& aMetadata,
|
|||
mAnimationState.emplace(mAnimationMode);
|
||||
mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize);
|
||||
|
||||
// We don't support discarding animated images (See bug 414259).
|
||||
// Lock the image and throw away the key.
|
||||
LockImage();
|
||||
if (!gfxPrefs::ImageMemAnimatedDiscardable()) {
|
||||
// We don't support discarding animated images (See bug 414259).
|
||||
// Lock the image and throw away the key.
|
||||
LockImage();
|
||||
}
|
||||
|
||||
if (!aFromMetadataDecode) {
|
||||
// The metadata decode reported that this image isn't animated, but we
|
||||
|
|
@ -1015,11 +1039,16 @@ RasterImage::Discard()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(CanDiscard(), "Asked to discard but can't");
|
||||
MOZ_ASSERT(!mAnimationState, "Asked to discard for animated image");
|
||||
MOZ_ASSERT(!mAnimationState || gfxPrefs::ImageMemAnimatedDiscardable(),
|
||||
"Asked to discard for animated image");
|
||||
|
||||
// Delete all the decoded frames.
|
||||
SurfaceCache::RemoveImage(ImageKey(this));
|
||||
|
||||
if (mAnimationState) {
|
||||
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
|
||||
}
|
||||
|
||||
// Notify that we discarded.
|
||||
if (mProgressTracker) {
|
||||
mProgressTracker->OnDiscard();
|
||||
|
|
@ -1028,8 +1057,8 @@ RasterImage::Discard()
|
|||
|
||||
bool
|
||||
RasterImage::CanDiscard() {
|
||||
return mHasSourceData && // ...have the source data...
|
||||
!mAnimationState; // Can never discard animated images
|
||||
return mHasSourceData && // ...have the source data...
|
||||
(!mAnimationState || gfxPrefs::ImageMemAnimatedDiscardable()); // Can discard animated images if the pref is set
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
@ -1158,6 +1187,13 @@ RasterImage::Decode(const IntSize& aSize,
|
|||
task = DecoderFactory::CreateAnimationDecoder(mDecoderType, WrapNotNull(this),
|
||||
mSourceBuffer, mSize,
|
||||
decoderFlags, surfaceFlags);
|
||||
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
|
||||
// If the animation is finished we can draw right away because we just draw
|
||||
// the final frame all the time from now on. See comment in
|
||||
// AnimationState::UpdateState.
|
||||
if (mAnimationFinished) {
|
||||
mAnimationState->SetCompositedFrameInvalid(false);
|
||||
}
|
||||
} else {
|
||||
task = DecoderFactory::CreateDecoder(mDecoderType, WrapNotNull(this),
|
||||
mSourceBuffer, mSize, aSize,
|
||||
|
|
@ -1597,7 +1633,8 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
|
|||
mHasBeenDecoded && mAnimationState) {
|
||||
// We've finished a full decode of all animation frames and our AnimationState
|
||||
// has been notified about them all, so let it know not to expect anymore.
|
||||
mAnimationState->SetDoneDecoding(true);
|
||||
mAnimationState->NotifyDecodeComplete();
|
||||
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
|
||||
}
|
||||
|
||||
// Only act on errors if we have no usable frames from the decoder.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue