diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /image/AnimationSurfaceProvider.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream/115.8.0esr.tar.xz firefox-esr-upstream/115.8.0esr.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'image/AnimationSurfaceProvider.h')
-rw-r--r-- | image/AnimationSurfaceProvider.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/image/AnimationSurfaceProvider.h b/image/AnimationSurfaceProvider.h new file mode 100644 index 0000000000..920638279e --- /dev/null +++ b/image/AnimationSurfaceProvider.h @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/** + * An ISurfaceProvider for animated images. + */ + +#ifndef mozilla_image_AnimationSurfaceProvider_h +#define mozilla_image_AnimationSurfaceProvider_h + +#include "mozilla/UniquePtr.h" + +#include "Decoder.h" +#include "FrameAnimator.h" +#include "IDecodingTask.h" +#include "ISurfaceProvider.h" +#include "AnimationFrameBuffer.h" + +namespace mozilla { +namespace layers { +class SharedSurfacesAnimation; +} + +namespace image { + +/** + * An ISurfaceProvider that manages the decoding of animated images and + * dynamically generates surfaces for the current playback state of the + * animation. + */ +class AnimationSurfaceProvider final : public ISurfaceProvider, + public IDecodingTask, + public IDecoderFrameRecycler { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override) + + AnimationSurfaceProvider(NotNull<RasterImage*> aImage, + const SurfaceKey& aSurfaceKey, + NotNull<Decoder*> aDecoder, size_t aCurrentFrame); + + ////////////////////////////////////////////////////////////////////////////// + // ISurfaceProvider implementation. + ////////////////////////////////////////////////////////////////////////////// + + public: + bool IsFinished() const override; + bool IsFullyDecoded() const override; + size_t LogicalSizeInBytes() const override; + void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, + const AddSizeOfCb& aCallback) override; + void Reset() override; + void Advance(size_t aFrame) override; + bool MayAdvance() const override { return mCompositedFrameRequested; } + void MarkMayAdvance() override { mCompositedFrameRequested = true; } + + protected: + DrawableFrameRef DrawableRef(size_t aFrame) override; + already_AddRefed<imgFrame> GetFrame(size_t aFrame) override; + + // Animation frames are always locked. This is because we only want to release + // their memory atomically (due to the surface cache discarding them). If they + // were unlocked, the OS could end up releasing the memory of random frames + // from the middle of the animation, which is not worth the complexity of + // dealing with. + bool IsLocked() const override { return true; } + void SetLocked(bool) override {} + + ////////////////////////////////////////////////////////////////////////////// + // IDecodingTask implementation. + ////////////////////////////////////////////////////////////////////////////// + + public: + void Run() override; + bool ShouldPreferSyncRun() const override; + + // Full decodes are low priority compared to metadata decodes because they + // don't block layout or page load. + TaskPriority Priority() const override { return TaskPriority::eLow; } + + ////////////////////////////////////////////////////////////////////////////// + // IDecoderFrameRecycler implementation. + ////////////////////////////////////////////////////////////////////////////// + + public: + RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) override; + + ////////////////////////////////////////////////////////////////////////////// + // IDecoderFrameRecycler implementation. + ////////////////////////////////////////////////////////////////////////////// + + public: + nsresult UpdateKey(layers::RenderRootStateManager* aManager, + wr::IpcResourceUpdateQueue& aResources, + wr::ImageKey& aKey) override; + + private: + virtual ~AnimationSurfaceProvider(); + + void DropImageReference(); + void AnnounceSurfaceAvailable(); + void FinishDecoding(); + void RequestFrameDiscarding(); + + // @returns Whether or not we should continue decoding. + bool CheckForNewFrameAtYield(); + + // @returns Whether or not we should restart decoding. + bool CheckForNewFrameAtTerminalState(); + + /// The image associated with our decoder. + RefPtr<RasterImage> mImage; + + /// A mutex to protect mDecoder. Always taken before mFramesMutex. + mutable Mutex mDecodingMutex MOZ_UNANNOTATED; + + /// The decoder used to decode this animation. + RefPtr<Decoder> mDecoder; + + /// A mutex to protect mFrames. Always taken after mDecodingMutex. + mutable Mutex mFramesMutex MOZ_UNANNOTATED; + + /// The frames of this animation, in order. + UniquePtr<AnimationFrameBuffer> mFrames; + + /// Whether the current frame was requested for display since the last time we + /// advanced the animation. + bool mCompositedFrameRequested; + + /// + RefPtr<layers::SharedSurfacesAnimation> mSharedAnimation; +}; + +} // namespace image +} // namespace mozilla + +#endif // mozilla_image_AnimationSurfaceProvider_h |