зеркало из https://github.com/mozilla/gecko-dev.git
114 строки
3.7 KiB
C++
114 строки
3.7 KiB
C++
/* -*- 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 "FrameAnimator.h"
|
|
#include "IDecodingTask.h"
|
|
#include "ISurfaceProvider.h"
|
|
#include "AnimationFrameBuffer.h"
|
|
|
|
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
|
|
{
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AnimationSurfaceProvider, override)
|
|
|
|
AnimationSurfaceProvider(NotNull<RasterImage*> aImage,
|
|
const SurfaceKey& aSurfaceKey,
|
|
NotNull<Decoder*> aDecoder,
|
|
size_t aCurrentFrame);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// 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;
|
|
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;
|
|
|
|
protected:
|
|
DrawableFrameRef DrawableRef(size_t aFrame) override;
|
|
RawAccessFrameRef RawAccessRef(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; }
|
|
|
|
private:
|
|
virtual ~AnimationSurfaceProvider();
|
|
|
|
void DropImageReference();
|
|
void AnnounceSurfaceAvailable();
|
|
void FinishDecoding();
|
|
|
|
// @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;
|
|
|
|
/// 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.
|
|
AnimationFrameBuffer mFrames;
|
|
};
|
|
|
|
} // namespace image
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_image_AnimationSurfaceProvider_h
|