|
Packit |
f0b94e |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
Packit |
f0b94e |
*
|
|
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 |
#ifndef mozilla_image_FrameAnimator_h
|
|
Packit |
f0b94e |
#define mozilla_image_FrameAnimator_h
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "mozilla/Maybe.h"
|
|
Packit |
f0b94e |
#include "mozilla/MemoryReporting.h"
|
|
Packit |
f0b94e |
#include "mozilla/TimeStamp.h"
|
|
Packit |
f0b94e |
#include "gfxTypes.h"
|
|
Packit |
f0b94e |
#include "imgFrame.h"
|
|
Packit |
f0b94e |
#include "nsCOMPtr.h"
|
|
Packit |
f0b94e |
#include "nsRect.h"
|
|
Packit |
f0b94e |
#include "SurfaceCache.h"
|
|
Packit |
f0b94e |
#include "gfxPrefs.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace mozilla {
|
|
Packit |
f0b94e |
namespace image {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class RasterImage;
|
|
Packit |
f0b94e |
class DrawableSurface;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class AnimationState {
|
|
Packit |
f0b94e |
public:
|
|
Packit |
f0b94e |
explicit AnimationState(uint16_t aAnimationMode)
|
|
Packit |
f0b94e |
: mFrameCount(0),
|
|
Packit |
f0b94e |
mCurrentAnimationFrameIndex(0),
|
|
Packit |
f0b94e |
mLoopRemainingCount(-1),
|
|
Packit |
f0b94e |
mLoopCount(-1),
|
|
Packit |
f0b94e |
mFirstFrameTimeout(FrameTimeout::FromRawMilliseconds(0)),
|
|
Packit |
f0b94e |
mAnimationMode(aAnimationMode),
|
|
Packit |
f0b94e |
mHasBeenDecoded(false),
|
|
Packit |
f0b94e |
mHasRequestedDecode(false),
|
|
Packit |
f0b94e |
mIsCurrentlyDecoded(false),
|
|
Packit |
f0b94e |
mCompositedFrameInvalid(false),
|
|
Packit |
f0b94e |
mDiscarded(false) {}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Call this whenever a decode completes, a decode starts, or the image is
|
|
Packit |
f0b94e |
* discarded. It will update the internal state. Specifically mDiscarded,
|
|
Packit |
f0b94e |
* mCompositedFrameInvalid, and mIsCurrentlyDecoded. If aAllowInvalidation
|
|
Packit |
f0b94e |
* is true then returns a rect to invalidate.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
const gfx::IntRect UpdateState(bool aAnimationFinished, RasterImage* aImage,
|
|
Packit |
f0b94e |
const gfx::IntSize& aSize,
|
|
Packit |
f0b94e |
bool aAllowInvalidation = true);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
private:
|
|
Packit |
f0b94e |
const gfx::IntRect UpdateStateInternal(LookupResult& aResult,
|
|
Packit |
f0b94e |
bool aAnimationFinished,
|
|
Packit |
f0b94e |
const gfx::IntSize& aSize,
|
|
Packit |
f0b94e |
bool aAllowInvalidation = true);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
public:
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Call when a decode of this image has been completed.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void NotifyDecodeComplete();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Returns true if this image has been fully decoded before.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool GetHasBeenDecoded() { return mHasBeenDecoded; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Returns true if this image has ever requested a decode before.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool GetHasRequestedDecode() { return mHasRequestedDecode; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Returns true if this image has been discarded and a decoded has not yet
|
|
Packit |
f0b94e |
* been created to redecode it.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool IsDiscarded() { return mDiscarded; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Sets the composited frame as valid or invalid.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetCompositedFrameInvalid(bool aInvalid) {
|
|
Packit |
f0b94e |
MOZ_ASSERT(!aInvalid || gfxPrefs::ImageMemAnimatedDiscardable());
|
|
Packit |
f0b94e |
mCompositedFrameInvalid = aInvalid;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Returns whether the composited frame is valid to draw to the screen.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool GetCompositedFrameInvalid() { return mCompositedFrameInvalid; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Returns whether the image is currently full decoded..
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool GetIsCurrentlyDecoded() { return mIsCurrentlyDecoded; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Call when you need to re-start animating. Ensures we start from the first
|
|
Packit |
f0b94e |
* frame.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void ResetAnimation();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* The animation mode of the image.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Constants defined in imgIContainer.idl.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetAnimationMode(uint16_t aAnimationMode);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// Update the number of frames of animation this image is known to have.
|
|
Packit |
f0b94e |
void UpdateKnownFrameCount(uint32_t aFrameCount);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// @return the number of frames of animation we know about so far.
|
|
Packit |
f0b94e |
uint32_t KnownFrameCount() const { return mFrameCount; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// @return the number of frames this animation has, if we know for sure.
|
|
Packit |
f0b94e |
/// (In other words, if decoding is finished.) Otherwise, returns Nothing().
|
|
Packit |
f0b94e |
Maybe<uint32_t> FrameCount() const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Get or set the area of the image to invalidate when we loop around to the
|
|
Packit |
f0b94e |
* first frame.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetFirstFrameRefreshArea(const gfx::IntRect& aRefreshArea);
|
|
Packit |
f0b94e |
gfx::IntRect FirstFrameRefreshArea() const { return mFirstFrameRefreshArea; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* If the animation frame time has not yet been set, set it to
|
|
Packit |
f0b94e |
* TimeStamp::Now().
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void InitAnimationFrameTimeIfNecessary();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Set the animation frame time to @aTime.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetAnimationFrameTime(const TimeStamp& aTime);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* The current frame we're on, from 0 to (numFrames - 1).
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
uint32_t GetCurrentAnimationFrameIndex() const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Set number of times to loop the image.
|
|
Packit |
f0b94e |
* @note -1 means loop forever.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetLoopCount(int32_t aLoopCount) { mLoopCount = aLoopCount; }
|
|
Packit |
f0b94e |
int32_t LoopCount() const { return mLoopCount; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// Set the @aLength of a single loop through this image.
|
|
Packit |
f0b94e |
void SetLoopLength(FrameTimeout aLength) { mLoopLength = Some(aLength); }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* @return the length of a single loop of this image. If this image is not
|
|
Packit |
f0b94e |
* finished decoding, is not animated, or it is animated but does not loop,
|
|
Packit |
f0b94e |
* returns FrameTimeout::Forever().
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
FrameTimeout LoopLength() const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Get or set the timeout for the first frame. This is used to allow animation
|
|
Packit |
f0b94e |
* scheduling even before a full decode runs for this image.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void SetFirstFrameTimeout(FrameTimeout aTimeout) {
|
|
Packit |
f0b94e |
mFirstFrameTimeout = aTimeout;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
FrameTimeout FirstFrameTimeout() const { return mFirstFrameTimeout; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
private:
|
|
Packit |
f0b94e |
friend class FrameAnimator;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Area of the first frame that needs to be redrawn on subsequent loops.
|
|
Packit |
f0b94e |
gfx::IntRect mFirstFrameRefreshArea;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! the time that the animation advanced to the current frame
|
|
Packit |
f0b94e |
TimeStamp mCurrentAnimationFrameTime;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The number of frames of animation this image has.
|
|
Packit |
f0b94e |
uint32_t mFrameCount;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The current frame index we're on, in the range [0, mFrameCount).
|
|
Packit |
f0b94e |
uint32_t mCurrentAnimationFrameIndex;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! number of loops remaining before animation stops (-1 no stop)
|
|
Packit |
f0b94e |
int32_t mLoopRemainingCount;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The total number of loops for the image.
|
|
Packit |
f0b94e |
int32_t mLoopCount;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The length of a single loop through this image.
|
|
Packit |
f0b94e |
Maybe<FrameTimeout> mLoopLength;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The timeout for the first frame of this image.
|
|
Packit |
f0b94e |
FrameTimeout mFirstFrameTimeout;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The animation mode of this image. Constants defined in imgIContainer.
|
|
Packit |
f0b94e |
uint16_t mAnimationMode;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* The following four bools (mHasBeenDecoded, mIsCurrentlyDecoded,
|
|
Packit |
f0b94e |
* mCompositedFrameInvalid, mDiscarded) track the state of the image with
|
|
Packit |
f0b94e |
* regards to decoding. They all start out false, including mDiscarded,
|
|
Packit |
f0b94e |
* because we want to treat being discarded differently from "not yet decoded
|
|
Packit |
f0b94e |
* for the first time".
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* (When we are decoding the image for the first time we want to show the
|
|
Packit |
f0b94e |
* image at the speed of data coming in from the network or the speed
|
|
Packit |
f0b94e |
* specified in the image file, whichever is slower. But when redecoding we
|
|
Packit |
f0b94e |
* want to show nothing until the frame for the current time has been
|
|
Packit |
f0b94e |
* decoded. The prevents the user from seeing the image "fast forward"
|
|
Packit |
f0b94e |
* to the expected spot.)
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* When the image is decoded for the first time mHasBeenDecoded and
|
|
Packit |
f0b94e |
* mIsCurrentlyDecoded get set to true. When the image is discarded
|
|
Packit |
f0b94e |
* mIsCurrentlyDecoded gets set to false, and mCompositedFrameInvalid
|
|
Packit |
f0b94e |
* & mDiscarded get set to true. When we create a decoder to redecode the
|
|
Packit |
f0b94e |
* image mDiscarded gets set to false. mCompositedFrameInvalid gets set to
|
|
Packit |
f0b94e |
* false when we are able to advance to the frame that should be showing
|
|
Packit |
f0b94e |
* for the current time. mIsCurrentlyDecoded gets set to true when the
|
|
Packit |
f0b94e |
* redecode finishes.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Whether this image has been decoded at least once.
|
|
Packit |
f0b94e |
bool mHasBeenDecoded;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Whether this image has ever requested a decode.
|
|
Packit |
f0b94e |
bool mHasRequestedDecode;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Whether this image is currently fully decoded.
|
|
Packit |
f0b94e |
bool mIsCurrentlyDecoded;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Whether the composited frame is valid to draw to the screen, note that
|
|
Packit |
f0b94e |
//! the composited frame can exist and be filled with image data but not
|
|
Packit |
f0b94e |
//! valid to draw to the screen.
|
|
Packit |
f0b94e |
bool mCompositedFrameInvalid;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Whether this image is currently discarded. Only set to true after the
|
|
Packit |
f0b94e |
//! image has been decoded at least once.
|
|
Packit |
f0b94e |
bool mDiscarded;
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* RefreshResult is used to let callers know how the state of the animation
|
|
Packit |
f0b94e |
* changed during a call to FrameAnimator::RequestRefresh().
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
struct RefreshResult {
|
|
Packit |
f0b94e |
RefreshResult() : mFrameAdvanced(false), mAnimationFinished(false) {}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// Merges another RefreshResult's changes into this RefreshResult.
|
|
Packit |
f0b94e |
void Accumulate(const RefreshResult& aOther) {
|
|
Packit |
f0b94e |
mFrameAdvanced = mFrameAdvanced || aOther.mFrameAdvanced;
|
|
Packit |
f0b94e |
mAnimationFinished = mAnimationFinished || aOther.mAnimationFinished;
|
|
Packit |
f0b94e |
mDirtyRect = mDirtyRect.Union(aOther.mDirtyRect);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// The region of the image that has changed.
|
|
Packit |
f0b94e |
gfx::IntRect mDirtyRect;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// If true, we changed frames at least once. Note that, due to looping, we
|
|
Packit |
f0b94e |
// could still have ended up on the same frame!
|
|
Packit |
f0b94e |
bool mFrameAdvanced : 1;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Whether the animation has finished playing.
|
|
Packit |
f0b94e |
bool mAnimationFinished : 1;
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class FrameAnimator {
|
|
Packit |
f0b94e |
public:
|
|
Packit |
f0b94e |
FrameAnimator(RasterImage* aImage, const gfx::IntSize& aSize)
|
|
Packit |
f0b94e |
: mImage(aImage), mSize(aSize), mLastCompositedFrameIndex(-1) {
|
|
Packit |
f0b94e |
MOZ_COUNT_CTOR(FrameAnimator);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
~FrameAnimator() { MOZ_COUNT_DTOR(FrameAnimator); }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Call when you need to re-start animating. Ensures we start from the first
|
|
Packit |
f0b94e |
* frame.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void ResetAnimation(AnimationState& aState);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Re-evaluate what frame we're supposed to be on, and do whatever blending
|
|
Packit |
f0b94e |
* is necessary to get us to that frame.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Returns the result of that blending, including whether the current frame
|
|
Packit |
f0b94e |
* changed and what the resulting dirty rectangle is.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RefreshResult RequestRefresh(AnimationState& aState, const TimeStamp& aTime,
|
|
Packit |
f0b94e |
bool aAnimationFinished);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Get the full frame for the current frame of the animation (it may or may
|
|
Packit |
f0b94e |
* not have required compositing). It may not be available because it hasn't
|
|
Packit |
f0b94e |
* been decoded yet, in which case we return an empty LookupResult.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
LookupResult GetCompositedFrame(AnimationState& aState);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Collect an accounting of the memory occupied by the compositing surfaces we
|
|
Packit |
f0b94e |
* use during animation playback. All of the actual animation frames are
|
|
Packit |
f0b94e |
* stored in the SurfaceCache, so we don't need to report them here.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
void CollectSizeOfCompositingSurfaces(
|
|
Packit |
f0b94e |
nsTArray<SurfaceMemoryCounter>& aCounters,
|
|
Packit |
f0b94e |
MallocSizeOf aMallocSizeOf) const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
private: // methods
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Advances the animation. Typically, this will advance a single frame, but it
|
|
Packit |
f0b94e |
* may advance multiple frames. This may happen if we have infrequently
|
|
Packit |
f0b94e |
* "ticking" refresh drivers (e.g. in background tabs), or extremely short-
|
|
Packit |
f0b94e |
* lived animation frames.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* @param aTime the time that the animation should advance to. This will
|
|
Packit |
f0b94e |
* typically be <= TimeStamp::Now().
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* @returns a RefreshResult that shows whether the frame was successfully
|
|
Packit |
f0b94e |
* advanced, and its resulting dirty rect.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RefreshResult AdvanceFrame(AnimationState& aState, DrawableSurface& aFrames,
|
|
Packit |
f0b94e |
TimeStamp aTime);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Get the @aIndex-th frame in the frame index, ignoring results of blending.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RawAccessFrameRef GetRawFrame(DrawableSurface& aFrames,
|
|
Packit |
f0b94e |
uint32_t aFrameNum) const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/// @return the given frame's timeout if it is available
|
|
Packit |
f0b94e |
Maybe<FrameTimeout> GetTimeoutForFrame(AnimationState& aState,
|
|
Packit |
f0b94e |
DrawableSurface& aFrames,
|
|
Packit |
f0b94e |
uint32_t aFrameNum) const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Get the time the frame we're currently displaying is supposed to end.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* In the error case (like if the requested frame is not currently
|
|
Packit |
f0b94e |
* decoded), returns None().
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
Maybe<TimeStamp> GetCurrentImgFrameEndTime(AnimationState& aState,
|
|
Packit |
f0b94e |
DrawableSurface& aFrames) const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool DoBlend(DrawableSurface& aFrames, gfx::IntRect* aDirtyRect,
|
|
Packit |
f0b94e |
uint32_t aPrevFrameIndex, uint32_t aNextFrameIndex);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/** Clears an area of <aFrame> with transparent black.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* @param aFrameData Target Frame data
|
|
Packit |
f0b94e |
* @param aFrameRect The rectangle of the data pointed ot by aFrameData
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* @note Does also clears the transparency mask
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
static void ClearFrame(uint8_t* aFrameData, const gfx::IntRect& aFrameRect);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! @overload
|
|
Packit |
f0b94e |
static void ClearFrame(uint8_t* aFrameData, const gfx::IntRect& aFrameRect,
|
|
Packit |
f0b94e |
const gfx::IntRect& aRectToClear);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Copy one frame's image and mask into another
|
|
Packit |
f0b94e |
static bool CopyFrameImage(const uint8_t* aDataSrc,
|
|
Packit |
f0b94e |
const gfx::IntRect& aRectSrc, uint8_t* aDataDest,
|
|
Packit |
f0b94e |
const gfx::IntRect& aRectDest);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/**
|
|
Packit |
f0b94e |
* Draws one frame's image to into another, at the position specified by
|
|
Packit |
f0b94e |
* aSrcRect.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* @aSrcData the raw data of the current frame being drawn
|
|
Packit |
f0b94e |
* @aSrcRect the size of the source frame, and the position of that frame in
|
|
Packit |
f0b94e |
* the composition frame
|
|
Packit |
f0b94e |
* @aSrcPaletteLength the length (in bytes) of the palette at the beginning
|
|
Packit |
f0b94e |
* of the source data (0 if image is not paletted)
|
|
Packit |
f0b94e |
* @aSrcHasAlpha whether the source data represents an image with alpha
|
|
Packit |
f0b94e |
* @aDstPixels the raw data of the composition frame where the current frame
|
|
Packit |
f0b94e |
* is drawn into (32-bit ARGB)
|
|
Packit |
f0b94e |
* @aDstRect the size of the composition frame
|
|
Packit |
f0b94e |
* @aBlendMethod the blend method for how to blend src on the composition
|
|
Packit |
f0b94e |
* frame.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
static nsresult DrawFrameTo(const uint8_t* aSrcData,
|
|
Packit |
f0b94e |
const gfx::IntRect& aSrcRect,
|
|
Packit |
f0b94e |
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
|
|
Packit |
f0b94e |
uint8_t* aDstPixels, const gfx::IntRect& aDstRect,
|
|
Packit |
f0b94e |
BlendMethod aBlendMethod,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aBlendRect);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
private: // data
|
|
Packit |
f0b94e |
//! A weak pointer to our owning image.
|
|
Packit |
f0b94e |
RasterImage* mImage;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! The intrinsic size of the image.
|
|
Packit |
f0b94e |
gfx::IntSize mSize;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/** For managing blending of frames
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Some animations will use the compositingFrame to composite images
|
|
Packit |
f0b94e |
* and just hand this back to the caller when it is time to draw the frame.
|
|
Packit |
f0b94e |
* NOTE: When clearing compositingFrame, remember to set
|
|
Packit |
f0b94e |
* lastCompositedFrameIndex to -1. Code assume that if
|
|
Packit |
f0b94e |
* lastCompositedFrameIndex >= 0 then compositingFrame exists.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RawAccessFrameRef mCompositingFrame;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* The Previous Frame (all frames composited up to the current) needs to be
|
|
Packit |
f0b94e |
* stored in cases where the image specifies it wants the last frame back
|
|
Packit |
f0b94e |
* when it's done with the current frame.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RawAccessFrameRef mCompositingPrevFrame;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
//! Track the last composited frame for Optimizations (See DoComposite code)
|
|
Packit |
f0b94e |
int32_t mLastCompositedFrameIndex;
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} // namespace image
|
|
Packit |
f0b94e |
} // namespace mozilla
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#endif // mozilla_image_FrameAnimator_h
|