|
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
|