1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /** 7 * An ISurfaceProvider for animated images. 8 */ 9 10 #ifndef mozilla_image_AnimationSurfaceProvider_h 11 #define mozilla_image_AnimationSurfaceProvider_h 12 13 #include "mozilla/UniquePtr.h" 14 15 #include "Decoder.h" 16 #include "FrameAnimator.h" 17 #include "IDecodingTask.h" 18 #include "ISurfaceProvider.h" 19 #include "AnimationFrameBuffer.h" 20 21 namespace mozilla { 22 namespace image { 23 24 /** 25 * An ISurfaceProvider that manages the decoding of animated images and 26 * dynamically generates surfaces for the current playback state of the 27 * animation. 28 */ 29 class AnimationSurfaceProvider final : public ISurfaceProvider, 30 public IDecodingTask, 31 public IDecoderFrameRecycler { 32 public: 33 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override) 34 35 AnimationSurfaceProvider(NotNull<RasterImage*> aImage, 36 const SurfaceKey& aSurfaceKey, 37 NotNull<Decoder*> aDecoder, size_t aCurrentFrame); 38 39 ////////////////////////////////////////////////////////////////////////////// 40 // ISurfaceProvider implementation. 41 ////////////////////////////////////////////////////////////////////////////// 42 43 public: 44 // We use the ISurfaceProvider constructor of DrawableSurface to indicate that 45 // our surfaces are computed lazily. Surface()46 DrawableSurface Surface() override { 47 return DrawableSurface(WrapNotNull(this)); 48 } 49 50 bool IsFinished() const override; 51 bool IsFullyDecoded() const override; 52 size_t LogicalSizeInBytes() const override; 53 void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, 54 const AddSizeOfCb& aCallback) override; 55 void Reset() override; 56 void Advance(size_t aFrame) override; 57 58 protected: 59 DrawableFrameRef DrawableRef(size_t aFrame) override; 60 already_AddRefed<imgFrame> GetFrame(size_t aFrame) override; 61 62 // Animation frames are always locked. This is because we only want to release 63 // their memory atomically (due to the surface cache discarding them). If they 64 // were unlocked, the OS could end up releasing the memory of random frames 65 // from the middle of the animation, which is not worth the complexity of 66 // dealing with. IsLocked()67 bool IsLocked() const override { return true; } SetLocked(bool)68 void SetLocked(bool) override {} 69 70 ////////////////////////////////////////////////////////////////////////////// 71 // IDecodingTask implementation. 72 ////////////////////////////////////////////////////////////////////////////// 73 74 public: 75 void Run() override; 76 bool ShouldPreferSyncRun() const override; 77 78 // Full decodes are low priority compared to metadata decodes because they 79 // don't block layout or page load. Priority()80 TaskPriority Priority() const override { return TaskPriority::eLow; } 81 82 ////////////////////////////////////////////////////////////////////////////// 83 // IDecoderFrameRecycler implementation. 84 ////////////////////////////////////////////////////////////////////////////// 85 86 public: 87 RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) override; 88 89 private: 90 virtual ~AnimationSurfaceProvider(); 91 92 void DropImageReference(); 93 void AnnounceSurfaceAvailable(); 94 void FinishDecoding(); 95 void RequestFrameDiscarding(); 96 97 // @returns Whether or not we should continue decoding. 98 bool CheckForNewFrameAtYield(); 99 100 // @returns Whether or not we should restart decoding. 101 bool CheckForNewFrameAtTerminalState(); 102 103 /// The image associated with our decoder. 104 RefPtr<RasterImage> mImage; 105 106 /// A mutex to protect mDecoder. Always taken before mFramesMutex. 107 mutable Mutex mDecodingMutex; 108 109 /// The decoder used to decode this animation. 110 RefPtr<Decoder> mDecoder; 111 112 /// A mutex to protect mFrames. Always taken after mDecodingMutex. 113 mutable Mutex mFramesMutex; 114 115 /// The frames of this animation, in order. 116 UniquePtr<AnimationFrameBuffer> mFrames; 117 }; 118 119 } // namespace image 120 } // namespace mozilla 121 122 #endif // mozilla_image_AnimationSurfaceProvider_h 123