gecko-dev/image/FrameAnimator.h

309 строки
9.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/. */
Bug 1038536 - Flatten image/src/ directory. r=seth --HG-- rename : image/src/BMPFileHeaders.h => image/BMPFileHeaders.h rename : image/src/ClippedImage.cpp => image/ClippedImage.cpp rename : image/src/ClippedImage.h => image/ClippedImage.h rename : image/src/DecodePool.cpp => image/DecodePool.cpp rename : image/src/DecodePool.h => image/DecodePool.h rename : image/src/Decoder.cpp => image/Decoder.cpp rename : image/src/Decoder.h => image/Decoder.h rename : image/src/Downscaler.cpp => image/Downscaler.cpp rename : image/src/Downscaler.h => image/Downscaler.h rename : image/src/DynamicImage.cpp => image/DynamicImage.cpp rename : image/src/DynamicImage.h => image/DynamicImage.h rename : image/src/FrameAnimator.cpp => image/FrameAnimator.cpp rename : image/src/FrameAnimator.h => image/FrameAnimator.h rename : image/src/FrozenImage.cpp => image/FrozenImage.cpp rename : image/src/FrozenImage.h => image/FrozenImage.h rename : image/src/ICOFileHeaders.h => image/ICOFileHeaders.h rename : image/src/IProgressObserver.h => image/IProgressObserver.h rename : image/src/Image.cpp => image/Image.cpp rename : image/src/Image.h => image/Image.h rename : image/src/ImageFactory.cpp => image/ImageFactory.cpp rename : image/src/ImageFactory.h => image/ImageFactory.h rename : image/src/ImageMetadata.cpp => image/ImageMetadata.cpp rename : image/src/ImageMetadata.h => image/ImageMetadata.h rename : image/src/ImageOps.cpp => image/ImageOps.cpp rename : image/src/ImageOps.h => image/ImageOps.h rename : image/src/ImageRegion.h => image/ImageRegion.h rename : image/src/ImageURL.h => image/ImageURL.h rename : image/src/ImageWrapper.cpp => image/ImageWrapper.cpp rename : image/src/ImageWrapper.h => image/ImageWrapper.h rename : image/src/MultipartImage.cpp => image/MultipartImage.cpp rename : image/src/MultipartImage.h => image/MultipartImage.h rename : image/src/Orientation.h => image/Orientation.h rename : image/src/OrientedImage.cpp => image/OrientedImage.cpp rename : image/src/OrientedImage.h => image/OrientedImage.h rename : image/src/ProgressTracker.cpp => image/ProgressTracker.cpp rename : image/src/ProgressTracker.h => image/ProgressTracker.h rename : image/src/RasterImage.cpp => image/RasterImage.cpp rename : image/src/RasterImage.h => image/RasterImage.h rename : image/src/SVGDocumentWrapper.cpp => image/SVGDocumentWrapper.cpp rename : image/src/SVGDocumentWrapper.h => image/SVGDocumentWrapper.h rename : image/src/ScriptedNotificationObserver.cpp => image/ScriptedNotificationObserver.cpp rename : image/src/ScriptedNotificationObserver.h => image/ScriptedNotificationObserver.h rename : image/src/ShutdownTracker.cpp => image/ShutdownTracker.cpp rename : image/src/ShutdownTracker.h => image/ShutdownTracker.h rename : image/src/SourceBuffer.cpp => image/SourceBuffer.cpp rename : image/src/SourceBuffer.h => image/SourceBuffer.h rename : image/src/SurfaceCache.cpp => image/SurfaceCache.cpp rename : image/src/SurfaceCache.h => image/SurfaceCache.h rename : image/src/VectorImage.cpp => image/VectorImage.cpp rename : image/src/VectorImage.h => image/VectorImage.h rename : image/src/imgFrame.cpp => image/imgFrame.cpp rename : image/src/imgFrame.h => image/imgFrame.h rename : image/src/imgLoader.cpp => image/imgLoader.cpp rename : image/src/imgLoader.h => image/imgLoader.h rename : image/src/imgRequest.cpp => image/imgRequest.cpp rename : image/src/imgRequest.h => image/imgRequest.h rename : image/src/imgRequestProxy.cpp => image/imgRequestProxy.cpp rename : image/src/imgRequestProxy.h => image/imgRequestProxy.h rename : image/src/imgTools.cpp => image/imgTools.cpp rename : image/src/imgTools.h => image/imgTools.h
2015-05-15 06:52:05 +03:00
#ifndef mozilla_image_FrameAnimator_h
#define mozilla_image_FrameAnimator_h
#include "mozilla/Maybe.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TimeStamp.h"
#include "gfx2DGlue.h"
#include "gfxTypes.h"
#include "imgFrame.h"
#include "nsCOMPtr.h"
#include "nsRect.h"
#include "SurfaceCache.h"
namespace mozilla {
namespace image {
class RasterImage;
class AnimationState
{
public:
explicit AnimationState(uint16_t aAnimationMode)
: mCurrentAnimationFrameIndex(0)
, mLoopRemainingCount(-1)
, mLoopCount(-1)
, mFirstFrameTimeout(FrameTimeout::FromRawMilliseconds(0))
, mAnimationMode(aAnimationMode)
, mDoneDecoding(false)
{ }
/**
* Call when this image is finished decoding so we know that there aren't any
* more frames coming.
*/
void SetDoneDecoding(bool aDone);
/**
* Call when you need to re-start animating. Ensures we start from the first
* frame.
*/
void ResetAnimation();
/**
* The animation mode of the image.
*
* Constants defined in imgIContainer.idl.
*/
void SetAnimationMode(uint16_t aAnimationMode);
/**
* Union the area to refresh when we loop around to the first frame with this
* rect.
*/
void UnionFirstFrameRefreshArea(const nsIntRect& aRect);
/**
* If the animation frame time has not yet been set, set it to
* TimeStamp::Now().
*/
void InitAnimationFrameTimeIfNecessary();
/**
* Set the animation frame time to @aTime.
*/
void SetAnimationFrameTime(const TimeStamp& aTime);
/**
* The current frame we're on, from 0 to (numFrames - 1).
*/
uint32_t GetCurrentAnimationFrameIndex() const;
/**
* Get the area we refresh when we loop around to the first frame.
*/
nsIntRect GetFirstFrameRefreshArea() const;
/*
* Set number of times to loop the image.
* @note -1 means loop forever.
*/
void SetLoopCount(int32_t aLoopCount) { mLoopCount = aLoopCount; }
int32_t LoopCount() const { return mLoopCount; }
/*
* Get or set the timeout for the first frame. This is used to allow animation
* scheduling even before a full decode runs for this image.
*/
void SetFirstFrameTimeout(FrameTimeout aTimeout) { mFirstFrameTimeout = aTimeout; }
FrameTimeout FirstFrameTimeout() const { return mFirstFrameTimeout; }
private:
friend class FrameAnimator;
//! Area of the first frame that needs to be redrawn on subsequent loops.
nsIntRect mFirstFrameRefreshArea;
//! the time that the animation advanced to the current frame
TimeStamp mCurrentAnimationFrameTime;
//! The current frame index we're on. 0 to (numFrames - 1).
uint32_t mCurrentAnimationFrameIndex;
//! number of loops remaining before animation stops (-1 no stop)
int32_t mLoopRemainingCount;
//! The total number of loops for the image.
int32_t mLoopCount;
//! The timeout for the first frame of this image.
FrameTimeout mFirstFrameTimeout;
//! The animation mode of this image. Constants defined in imgIContainer.
uint16_t mAnimationMode;
//! Whether this image is done being decoded.
bool mDoneDecoding;
};
class FrameAnimator
{
public:
FrameAnimator(RasterImage* aImage, gfx::IntSize aSize)
: mImage(aImage)
, mSize(aSize)
, mLastCompositedFrameIndex(-1)
{
MOZ_COUNT_CTOR(FrameAnimator);
}
~FrameAnimator()
{
MOZ_COUNT_DTOR(FrameAnimator);
}
/**
* Return value from RequestRefresh. Tells callers what happened in that call
* to RequestRefresh.
*/
struct RefreshResult
{
// The dirty rectangle to be re-drawn after this RequestRefresh().
nsIntRect dirtyRect;
// Whether any frame changed, and hence the dirty rect was set.
bool frameAdvanced : 1;
// Whether the animation has finished playing.
bool animationFinished : 1;
RefreshResult()
: frameAdvanced(false)
, animationFinished(false)
{ }
void Accumulate(const RefreshResult& other)
{
frameAdvanced = frameAdvanced || other.frameAdvanced;
animationFinished = animationFinished || other.animationFinished;
dirtyRect = dirtyRect.Union(other.dirtyRect);
}
};
/**
* Re-evaluate what frame we're supposed to be on, and do whatever blending
* is necessary to get us to that frame.
*
* Returns the result of that blending, including whether the current frame
* changed and what the resulting dirty rectangle is.
*/
RefreshResult RequestRefresh(AnimationState& aState, const TimeStamp& aTime);
/**
* If we have a composited frame for @aFrameNum, returns it. Otherwise,
* returns an empty LookupResult. It is an error to call this method with
* aFrameNum == 0, because the first frame is never composited.
*/
LookupResult GetCompositedFrame(uint32_t aFrameNum);
/// @return the given frame's timeout.
FrameTimeout GetTimeoutForFrame(AnimationState& aState, uint32_t aFrameNum) const;
/**
* Collect an accounting of the memory occupied by the compositing surfaces we
* use during animation playback. All of the actual animation frames are
* stored in the SurfaceCache, so we don't need to report them here.
*/
void CollectSizeOfCompositingSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
MallocSizeOf aMallocSizeOf) const;
private: // methods
/**
* Advances the animation. Typically, this will advance a single frame, but it
* may advance multiple frames. This may happen if we have infrequently
* "ticking" refresh drivers (e.g. in background tabs), or extremely short-
* lived animation frames.
*
* @param aTime the time that the animation should advance to. This will
* typically be <= TimeStamp::Now().
*
* @returns a RefreshResult that shows whether the frame was successfully
* advanced, and its resulting dirty rect.
*/
RefreshResult AdvanceFrame(AnimationState& aState, TimeStamp aTime);
/**
* Get the @aIndex-th frame in the frame index, ignoring results of blending.
*/
RawAccessFrameRef GetRawFrame(uint32_t aFrameNum) const;
/**
* Gets the length of a single loop of this image, in milliseconds.
*
* If this image is not finished decoding, is not animated, or it is animated
* but does not loop, returns -1. Can return 0 in the case of an animated
* image that has a 0ms delay between its frames and does not loop.
*/
int32_t GetSingleLoopTime(AnimationState& aState) const;
/**
* Get the time the frame we're currently displaying is supposed to end.
*
* In the error case, returns an "infinity" timestamp.
*/
TimeStamp GetCurrentImgFrameEndTime(AnimationState& aState) const;
bool DoBlend(nsIntRect* aDirtyRect,
uint32_t aPrevFrameIndex,
uint32_t aNextFrameIndex);
/** Clears an area of <aFrame> with transparent black.
*
* @param aFrameData Target Frame data
* @param aFrameRect The rectangle of the data pointed ot by aFrameData
*
* @note Does also clears the transparency mask
*/
static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect);
//! @overload
static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect,
const nsIntRect& aRectToClear);
//! Copy one frame's image and mask into another
static bool CopyFrameImage(const uint8_t* aDataSrc, const nsIntRect& aRectSrc,
uint8_t* aDataDest, const nsIntRect& aRectDest);
/**
* Draws one frame's image to into another, at the position specified by
* aSrcRect.
*
* @aSrcData the raw data of the current frame being drawn
* @aSrcRect the size of the source frame, and the position of that frame in
* the composition frame
* @aSrcPaletteLength the length (in bytes) of the palette at the beginning
* of the source data (0 if image is not paletted)
* @aSrcHasAlpha whether the source data represents an image with alpha
* @aDstPixels the raw data of the composition frame where the current frame
* is drawn into (32-bit ARGB)
* @aDstRect the size of the composition frame
* @aBlendMethod the blend method for how to blend src on the composition
* frame.
*/
static nsresult DrawFrameTo(const uint8_t* aSrcData,
const nsIntRect& aSrcRect,
uint32_t aSrcPaletteLength, bool aSrcHasAlpha,
uint8_t* aDstPixels, const nsIntRect& aDstRect,
BlendMethod aBlendMethod,
const Maybe<nsIntRect>& aBlendRect);
private: // data
//! A weak pointer to our owning image.
RasterImage* mImage;
//! The intrinsic size of the image.
gfx::IntSize mSize;
/** For managing blending of frames
*
* Some animations will use the compositingFrame to composite images
* and just hand this back to the caller when it is time to draw the frame.
* NOTE: When clearing compositingFrame, remember to set
* lastCompositedFrameIndex to -1. Code assume that if
* lastCompositedFrameIndex >= 0 then compositingFrame exists.
*/
RawAccessFrameRef mCompositingFrame;
/** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
*
* The Previous Frame (all frames composited up to the current) needs to be
* stored in cases where the image specifies it wants the last frame back
* when it's done with the current frame.
*/
RawAccessFrameRef mCompositingPrevFrame;
//! Track the last composited frame for Optimizations (See DoComposite code)
int32_t mLastCompositedFrameIndex;
};
} // namespace image
} // namespace mozilla
Bug 1038536 - Flatten image/src/ directory. r=seth --HG-- rename : image/src/BMPFileHeaders.h => image/BMPFileHeaders.h rename : image/src/ClippedImage.cpp => image/ClippedImage.cpp rename : image/src/ClippedImage.h => image/ClippedImage.h rename : image/src/DecodePool.cpp => image/DecodePool.cpp rename : image/src/DecodePool.h => image/DecodePool.h rename : image/src/Decoder.cpp => image/Decoder.cpp rename : image/src/Decoder.h => image/Decoder.h rename : image/src/Downscaler.cpp => image/Downscaler.cpp rename : image/src/Downscaler.h => image/Downscaler.h rename : image/src/DynamicImage.cpp => image/DynamicImage.cpp rename : image/src/DynamicImage.h => image/DynamicImage.h rename : image/src/FrameAnimator.cpp => image/FrameAnimator.cpp rename : image/src/FrameAnimator.h => image/FrameAnimator.h rename : image/src/FrozenImage.cpp => image/FrozenImage.cpp rename : image/src/FrozenImage.h => image/FrozenImage.h rename : image/src/ICOFileHeaders.h => image/ICOFileHeaders.h rename : image/src/IProgressObserver.h => image/IProgressObserver.h rename : image/src/Image.cpp => image/Image.cpp rename : image/src/Image.h => image/Image.h rename : image/src/ImageFactory.cpp => image/ImageFactory.cpp rename : image/src/ImageFactory.h => image/ImageFactory.h rename : image/src/ImageMetadata.cpp => image/ImageMetadata.cpp rename : image/src/ImageMetadata.h => image/ImageMetadata.h rename : image/src/ImageOps.cpp => image/ImageOps.cpp rename : image/src/ImageOps.h => image/ImageOps.h rename : image/src/ImageRegion.h => image/ImageRegion.h rename : image/src/ImageURL.h => image/ImageURL.h rename : image/src/ImageWrapper.cpp => image/ImageWrapper.cpp rename : image/src/ImageWrapper.h => image/ImageWrapper.h rename : image/src/MultipartImage.cpp => image/MultipartImage.cpp rename : image/src/MultipartImage.h => image/MultipartImage.h rename : image/src/Orientation.h => image/Orientation.h rename : image/src/OrientedImage.cpp => image/OrientedImage.cpp rename : image/src/OrientedImage.h => image/OrientedImage.h rename : image/src/ProgressTracker.cpp => image/ProgressTracker.cpp rename : image/src/ProgressTracker.h => image/ProgressTracker.h rename : image/src/RasterImage.cpp => image/RasterImage.cpp rename : image/src/RasterImage.h => image/RasterImage.h rename : image/src/SVGDocumentWrapper.cpp => image/SVGDocumentWrapper.cpp rename : image/src/SVGDocumentWrapper.h => image/SVGDocumentWrapper.h rename : image/src/ScriptedNotificationObserver.cpp => image/ScriptedNotificationObserver.cpp rename : image/src/ScriptedNotificationObserver.h => image/ScriptedNotificationObserver.h rename : image/src/ShutdownTracker.cpp => image/ShutdownTracker.cpp rename : image/src/ShutdownTracker.h => image/ShutdownTracker.h rename : image/src/SourceBuffer.cpp => image/SourceBuffer.cpp rename : image/src/SourceBuffer.h => image/SourceBuffer.h rename : image/src/SurfaceCache.cpp => image/SurfaceCache.cpp rename : image/src/SurfaceCache.h => image/SurfaceCache.h rename : image/src/VectorImage.cpp => image/VectorImage.cpp rename : image/src/VectorImage.h => image/VectorImage.h rename : image/src/imgFrame.cpp => image/imgFrame.cpp rename : image/src/imgFrame.h => image/imgFrame.h rename : image/src/imgLoader.cpp => image/imgLoader.cpp rename : image/src/imgLoader.h => image/imgLoader.h rename : image/src/imgRequest.cpp => image/imgRequest.cpp rename : image/src/imgRequest.h => image/imgRequest.h rename : image/src/imgRequestProxy.cpp => image/imgRequestProxy.cpp rename : image/src/imgRequestProxy.h => image/imgRequestProxy.h rename : image/src/imgTools.cpp => image/imgTools.cpp rename : image/src/imgTools.h => image/imgTools.h
2015-05-15 06:52:05 +03:00
#endif // mozilla_image_FrameAnimator_h