2016-08-18 10:01:10 +03:00
|
|
|
/* -*- 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
|
|
|
|
|
2018-06-04 15:23:00 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
|
|
|
|
2018-06-04 15:33:16 +03:00
|
|
|
#include "Decoder.h"
|
2016-08-18 10:01:10 +03:00
|
|
|
#include "FrameAnimator.h"
|
|
|
|
#include "IDecodingTask.h"
|
|
|
|
#include "ISurfaceProvider.h"
|
2018-02-28 21:34:53 +03:00
|
|
|
#include "AnimationFrameBuffer.h"
|
2016-08-18 10:01:10 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
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,
|
2018-06-04 15:33:16 +03:00
|
|
|
public IDecoderFrameRecycler {
|
2016-08-18 10:01:10 +03:00
|
|
|
public:
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override)
|
|
|
|
|
|
|
|
AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
|
2016-08-25 00:50:49 +03:00
|
|
|
const SurfaceKey& aSurfaceKey,
|
2018-02-28 21:34:52 +03:00
|
|
|
NotNull<Decoder*> aDecoder, size_t aCurrentFrame);
|
2016-08-18 10:01:10 +03:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ISurfaceProvider implementation.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public:
|
|
|
|
// We use the ISurfaceProvider constructor of DrawableSurface to indicate that
|
|
|
|
// our surfaces are computed lazily.
|
|
|
|
DrawableSurface Surface() override {
|
|
|
|
return DrawableSurface(WrapNotNull(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsFinished() const override;
|
2018-02-28 21:34:53 +03:00
|
|
|
bool IsFullyDecoded() const override;
|
2016-08-18 10:01:10 +03:00
|
|
|
size_t LogicalSizeInBytes() const override;
|
2016-08-18 10:06:41 +03:00
|
|
|
void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
2018-09-25 16:13:51 +03:00
|
|
|
const AddSizeOfCb& aCallback) override;
|
2018-02-28 21:34:53 +03:00
|
|
|
void Reset() override;
|
|
|
|
void Advance(size_t aFrame) override;
|
2016-08-18 10:01:10 +03:00
|
|
|
|
|
|
|
protected:
|
|
|
|
DrawableFrameRef DrawableRef(size_t aFrame) override;
|
2018-06-04 01:49:23 +03:00
|
|
|
already_AddRefed<imgFrame> GetFrame(size_t aFrame) override;
|
2016-08-18 10:01:10 +03:00
|
|
|
|
|
|
|
// 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; }
|
|
|
|
|
2018-06-04 15:33:16 +03:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// IDecoderFrameRecycler implementation.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
public:
|
|
|
|
RawAccessFrameRef RecycleFrame(gfx::IntRect& aRecycleRect) override;
|
|
|
|
|
2016-08-18 10:01:10 +03:00
|
|
|
private:
|
|
|
|
virtual ~AnimationSurfaceProvider();
|
|
|
|
|
|
|
|
void DropImageReference();
|
|
|
|
void AnnounceSurfaceAvailable();
|
|
|
|
void FinishDecoding();
|
2018-06-04 15:23:00 +03:00
|
|
|
void RequestFrameDiscarding();
|
2016-08-18 10:01:10 +03:00
|
|
|
|
2018-02-28 21:34:53 +03:00
|
|
|
// @returns Whether or not we should continue decoding.
|
|
|
|
bool CheckForNewFrameAtYield();
|
|
|
|
|
|
|
|
// @returns Whether or not we should restart decoding.
|
|
|
|
bool CheckForNewFrameAtTerminalState();
|
|
|
|
|
2016-08-18 10:01:10 +03:00
|
|
|
/// The image associated with our decoder.
|
|
|
|
RefPtr<RasterImage> mImage;
|
|
|
|
|
|
|
|
/// A mutex to protect mDecoder. Always taken before mFramesMutex.
|
|
|
|
mutable Mutex mDecodingMutex;
|
|
|
|
|
|
|
|
/// The decoder used to decode this animation.
|
|
|
|
RefPtr<Decoder> mDecoder;
|
|
|
|
|
|
|
|
/// A mutex to protect mFrames. Always taken after mDecodingMutex.
|
|
|
|
mutable Mutex mFramesMutex;
|
|
|
|
|
|
|
|
/// The frames of this animation, in order.
|
2018-06-04 15:23:00 +03:00
|
|
|
UniquePtr<AnimationFrameBuffer> mFrames;
|
2016-08-18 10:01:10 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace image
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_image_AnimationSurfaceProvider_h
|