Blame image/AnimationSurfaceProvider.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * An ISurfaceProvider for animated images.
Packit f0b94e
 */
Packit f0b94e
Packit f0b94e
#ifndef mozilla_image_AnimationSurfaceProvider_h
Packit f0b94e
#define mozilla_image_AnimationSurfaceProvider_h
Packit f0b94e
Packit f0b94e
#include "FrameAnimator.h"
Packit f0b94e
#include "IDecodingTask.h"
Packit f0b94e
#include "ISurfaceProvider.h"
Packit f0b94e
#include "AnimationFrameBuffer.h"
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
namespace image {
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * An ISurfaceProvider that manages the decoding of animated images and
Packit f0b94e
 * dynamically generates surfaces for the current playback state of the
Packit f0b94e
 * animation.
Packit f0b94e
 */
Packit f0b94e
class AnimationSurfaceProvider final : public ISurfaceProvider,
Packit f0b94e
                                       public IDecodingTask {
Packit f0b94e
 public:
Packit f0b94e
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override)
Packit f0b94e
Packit f0b94e
  AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
Packit f0b94e
                           const SurfaceKey& aSurfaceKey,
Packit f0b94e
                           NotNull<Decoder*> aDecoder, size_t aCurrentFrame);
Packit f0b94e
Packit f0b94e
  //////////////////////////////////////////////////////////////////////////////
Packit f0b94e
  // ISurfaceProvider implementation.
Packit f0b94e
  //////////////////////////////////////////////////////////////////////////////
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  // We use the ISurfaceProvider constructor of DrawableSurface to indicate that
Packit f0b94e
  // our surfaces are computed lazily.
Packit f0b94e
  DrawableSurface Surface() override {
Packit f0b94e
    return DrawableSurface(WrapNotNull(this));
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool IsFinished() const override;
Packit f0b94e
  bool IsFullyDecoded() const override;
Packit f0b94e
  size_t LogicalSizeInBytes() const override;
Packit f0b94e
  void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, size_t& aHeapSizeOut,
Packit f0b94e
                              size_t& aNonHeapSizeOut,
Packit f0b94e
                              size_t& aExtHandlesOut) override;
Packit f0b94e
  void Reset() override;
Packit f0b94e
  void Advance(size_t aFrame) override;
Packit f0b94e
Packit f0b94e
 protected:
Packit f0b94e
  DrawableFrameRef DrawableRef(size_t aFrame) override;
Packit f0b94e
Packit f0b94e
  // Animation frames are always locked. This is because we only want to release
Packit f0b94e
  // their memory atomically (due to the surface cache discarding them). If they
Packit f0b94e
  // were unlocked, the OS could end up releasing the memory of random frames
Packit f0b94e
  // from the middle of the animation, which is not worth the complexity of
Packit f0b94e
  // dealing with.
Packit f0b94e
  bool IsLocked() const override { return true; }
Packit f0b94e
  void SetLocked(bool) override {}
Packit f0b94e
Packit f0b94e
  //////////////////////////////////////////////////////////////////////////////
Packit f0b94e
  // IDecodingTask implementation.
Packit f0b94e
  //////////////////////////////////////////////////////////////////////////////
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  void Run() override;
Packit f0b94e
  bool ShouldPreferSyncRun() const override;
Packit f0b94e
Packit f0b94e
  // Full decodes are low priority compared to metadata decodes because they
Packit f0b94e
  // don't block layout or page load.
Packit f0b94e
  TaskPriority Priority() const override { return TaskPriority::eLow; }
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  virtual ~AnimationSurfaceProvider();
Packit f0b94e
Packit f0b94e
  void DropImageReference();
Packit f0b94e
  void AnnounceSurfaceAvailable();
Packit f0b94e
  void FinishDecoding();
Packit f0b94e
Packit f0b94e
  // @returns Whether or not we should continue decoding.
Packit f0b94e
  bool CheckForNewFrameAtYield();
Packit f0b94e
Packit f0b94e
  // @returns Whether or not we should restart decoding.
Packit f0b94e
  bool CheckForNewFrameAtTerminalState();
Packit f0b94e
Packit f0b94e
  /// The image associated with our decoder.
Packit f0b94e
  RefPtr<RasterImage> mImage;
Packit f0b94e
Packit f0b94e
  /// A mutex to protect mDecoder. Always taken before mFramesMutex.
Packit f0b94e
  mutable Mutex mDecodingMutex;
Packit f0b94e
Packit f0b94e
  /// The decoder used to decode this animation.
Packit f0b94e
  RefPtr<Decoder> mDecoder;
Packit f0b94e
Packit f0b94e
  /// A mutex to protect mFrames. Always taken after mDecodingMutex.
Packit f0b94e
  mutable Mutex mFramesMutex;
Packit f0b94e
Packit f0b94e
  /// The frames of this animation, in order.
Packit f0b94e
  AnimationFrameBuffer mFrames;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
}  // namespace image
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif  // mozilla_image_AnimationSurfaceProvider_h