mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 18:47:53 +00:00
8c7d13e7f7
DrawableSurface only exposes DrawableFrameRef to its users. This is sufficient for the drawing related code in general, but FrameAnimator really needs RawAccessFrameRef to the underlying pixel data (which may be paletted). While one can get a RawAccessFrameRef from a DrawableFrameRef, it requires yet another lock of the imgFrame's mutex. We can avoid this extra lock if we just allow the callers to get the right data type in the first place.
116 lines
3.8 KiB
C++
116 lines
3.8 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,
|
|
size_t& aHeapSizeOut,
|
|
size_t& aNonHeapSizeOut,
|
|
size_t& aExtHandlesOut) 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
|