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 "FrameAnimator.h" 14 #include "IDecodingTask.h" 15 #include "ISurfaceProvider.h" 16 17 namespace mozilla { 18 namespace image { 19 20 /** 21 * An ISurfaceProvider that manages the decoding of animated images and 22 * dynamically generates surfaces for the current playback state of the 23 * animation. 24 */ 25 class AnimationSurfaceProvider final 26 : public ISurfaceProvider 27 , public IDecodingTask 28 { 29 public: 30 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override) 31 32 AnimationSurfaceProvider(NotNull<RasterImage*> aImage, 33 const SurfaceKey& aSurfaceKey, 34 NotNull<Decoder*> aDecoder); 35 36 37 ////////////////////////////////////////////////////////////////////////////// 38 // ISurfaceProvider implementation. 39 ////////////////////////////////////////////////////////////////////////////// 40 41 public: 42 // We use the ISurfaceProvider constructor of DrawableSurface to indicate that 43 // our surfaces are computed lazily. Surface()44 DrawableSurface Surface() override { return DrawableSurface(WrapNotNull(this)); } 45 46 bool IsFinished() const override; 47 size_t LogicalSizeInBytes() const override; 48 void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, 49 size_t& aHeapSizeOut, 50 size_t& aNonHeapSizeOut) override; 51 52 protected: 53 DrawableFrameRef DrawableRef(size_t aFrame) override; 54 55 // Animation frames are always locked. This is because we only want to release 56 // their memory atomically (due to the surface cache discarding them). If they 57 // were unlocked, the OS could end up releasing the memory of random frames 58 // from the middle of the animation, which is not worth the complexity of 59 // dealing with. IsLocked()60 bool IsLocked() const override { return true; } SetLocked(bool)61 void SetLocked(bool) override { } 62 63 64 ////////////////////////////////////////////////////////////////////////////// 65 // IDecodingTask implementation. 66 ////////////////////////////////////////////////////////////////////////////// 67 68 public: 69 void Run() override; 70 bool ShouldPreferSyncRun() const override; 71 72 // Full decodes are low priority compared to metadata decodes because they 73 // don't block layout or page load. Priority()74 TaskPriority Priority() const override { return TaskPriority::eLow; } 75 76 private: 77 virtual ~AnimationSurfaceProvider(); 78 79 void DropImageReference(); 80 void CheckForNewFrameAtYield(); 81 void CheckForNewFrameAtTerminalState(); 82 void AnnounceSurfaceAvailable(); 83 void FinishDecoding(); 84 85 /// The image associated with our decoder. 86 RefPtr<RasterImage> mImage; 87 88 /// A mutex to protect mDecoder. Always taken before mFramesMutex. 89 mutable Mutex mDecodingMutex; 90 91 /// The decoder used to decode this animation. 92 RefPtr<Decoder> mDecoder; 93 94 /// A mutex to protect mFrames. Always taken after mDecodingMutex. 95 mutable Mutex mFramesMutex; 96 97 /// The frames of this animation, in order. 98 nsTArray<RawAccessFrameRef> mFrames; 99 }; 100 101 } // namespace image 102 } // namespace mozilla 103 104 #endif // mozilla_image_AnimationSurfaceProvider_h 105