image/src/FrameAnimator.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 *
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef mozilla_imagelib_FrameAnimator_h_
michael@0 8 #define mozilla_imagelib_FrameAnimator_h_
michael@0 9
michael@0 10 #include "mozilla/TimeStamp.h"
michael@0 11 #include "nsRect.h"
michael@0 12
michael@0 13 namespace mozilla {
michael@0 14 namespace image {
michael@0 15
michael@0 16 class FrameBlender;
michael@0 17
michael@0 18 class FrameAnimator
michael@0 19 {
michael@0 20 public:
michael@0 21 FrameAnimator(FrameBlender& aBlender, uint16_t aAnimationMode);
michael@0 22
michael@0 23 /**
michael@0 24 * Return value from RequestRefresh. Tells callers what happened in that call
michael@0 25 * to RequestRefresh.
michael@0 26 */
michael@0 27 struct RefreshResult
michael@0 28 {
michael@0 29 // The dirty rectangle to be re-drawn after this RequestRefresh().
michael@0 30 nsIntRect dirtyRect;
michael@0 31
michael@0 32 // Whether any frame changed, and hence the dirty rect was set.
michael@0 33 bool frameAdvanced : 1;
michael@0 34
michael@0 35 // Whether the animation has finished playing.
michael@0 36 bool animationFinished : 1;
michael@0 37
michael@0 38 // Whether an error has occurred when trying to advance a frame. Note that
michael@0 39 // errors do not, on their own, end the animation.
michael@0 40 bool error : 1;
michael@0 41
michael@0 42 RefreshResult()
michael@0 43 : frameAdvanced(false)
michael@0 44 , animationFinished(false)
michael@0 45 , error(false)
michael@0 46 {}
michael@0 47
michael@0 48 void Accumulate(const RefreshResult& other)
michael@0 49 {
michael@0 50 frameAdvanced = frameAdvanced || other.frameAdvanced;
michael@0 51 animationFinished = animationFinished || other.animationFinished;
michael@0 52 error = error || other.error;
michael@0 53 dirtyRect = dirtyRect.Union(other.dirtyRect);
michael@0 54 }
michael@0 55 };
michael@0 56
michael@0 57 /**
michael@0 58 * Re-evaluate what frame we're supposed to be on, and do whatever blending
michael@0 59 * is necessary to get us to that frame.
michael@0 60 *
michael@0 61 * Returns the result of that blending, including whether the current frame
michael@0 62 * changed and what the resulting dirty rectangle is.
michael@0 63 */
michael@0 64 RefreshResult RequestRefresh(const mozilla::TimeStamp& aTime);
michael@0 65
michael@0 66 /**
michael@0 67 * Call when this image is finished decoding so we know that there aren't any
michael@0 68 * more frames coming.
michael@0 69 */
michael@0 70 void SetDoneDecoding(bool aDone);
michael@0 71
michael@0 72 /**
michael@0 73 * Call when you need to re-start animating. Ensures we start from the first
michael@0 74 * frame.
michael@0 75 */
michael@0 76 void ResetAnimation();
michael@0 77
michael@0 78 /**
michael@0 79 * The animation mode of the image.
michael@0 80 *
michael@0 81 * Constants defined in imgIContainer.idl.
michael@0 82 */
michael@0 83 void SetAnimationMode(uint16_t aAnimationMode);
michael@0 84
michael@0 85 /**
michael@0 86 * Set the area to refresh when we loop around to the first frame.
michael@0 87 */
michael@0 88 void SetFirstFrameRefreshArea(const nsIntRect& aRect);
michael@0 89
michael@0 90 /**
michael@0 91 * Union the area to refresh when we loop around to the first frame with this
michael@0 92 * rect.
michael@0 93 */
michael@0 94 void UnionFirstFrameRefreshArea(const nsIntRect& aRect);
michael@0 95
michael@0 96 /**
michael@0 97 * If the animation frame time has not yet been set, set it to
michael@0 98 * TimeStamp::Now().
michael@0 99 */
michael@0 100 void InitAnimationFrameTimeIfNecessary();
michael@0 101
michael@0 102 /**
michael@0 103 * Set the animation frame time to @aTime.
michael@0 104 */
michael@0 105 void SetAnimationFrameTime(const TimeStamp& aTime);
michael@0 106
michael@0 107 /**
michael@0 108 * The current frame we're on, from 0 to (numFrames - 1).
michael@0 109 */
michael@0 110 uint32_t GetCurrentAnimationFrameIndex() const;
michael@0 111
michael@0 112 /**
michael@0 113 * Get the area we refresh when we loop around to the first frame.
michael@0 114 */
michael@0 115 nsIntRect GetFirstFrameRefreshArea() const;
michael@0 116
michael@0 117 private: // methods
michael@0 118 /**
michael@0 119 * Gets the length of a single loop of this image, in milliseconds.
michael@0 120 *
michael@0 121 * If this image is not finished decoding, is not animated, or it is animated
michael@0 122 * but does not loop, returns -1. Can return 0 in the case of an animated image
michael@0 123 * that has a 0ms delay between its frames and does not loop.
michael@0 124 */
michael@0 125 int32_t GetSingleLoopTime() const;
michael@0 126
michael@0 127 /**
michael@0 128 * Advances the animation. Typically, this will advance a single frame, but it
michael@0 129 * may advance multiple frames. This may happen if we have infrequently
michael@0 130 * "ticking" refresh drivers (e.g. in background tabs), or extremely short-
michael@0 131 * lived animation frames.
michael@0 132 *
michael@0 133 * @param aTime the time that the animation should advance to. This will
michael@0 134 * typically be <= TimeStamp::Now().
michael@0 135 *
michael@0 136 * @returns a RefreshResult that shows whether the frame was successfully
michael@0 137 * advanced, and its resulting dirty rect.
michael@0 138 */
michael@0 139 RefreshResult AdvanceFrame(mozilla::TimeStamp aTime);
michael@0 140
michael@0 141 /**
michael@0 142 * Get the time the frame we're currently displaying is supposed to end.
michael@0 143 *
michael@0 144 * In the error case, returns an "infinity" timestamp.
michael@0 145 */
michael@0 146 mozilla::TimeStamp GetCurrentImgFrameEndTime() const;
michael@0 147
michael@0 148 private: // data
michael@0 149 //! Area of the first frame that needs to be redrawn on subsequent loops.
michael@0 150 nsIntRect mFirstFrameRefreshArea;
michael@0 151
michael@0 152 //! the time that the animation advanced to the current frame
michael@0 153 TimeStamp mCurrentAnimationFrameTime;
michael@0 154
michael@0 155 //! The current frame index we're on. 0 to (numFrames - 1).
michael@0 156 uint32_t mCurrentAnimationFrameIndex;
michael@0 157
michael@0 158 //! number of loops remaining before animation stops (-1 no stop)
michael@0 159 int32_t mLoopCounter;
michael@0 160
michael@0 161 //! All the frames of the image, shared with our owner
michael@0 162 FrameBlender& mFrameBlender;
michael@0 163
michael@0 164 //! The animation mode of this image. Constants defined in imgIContainer.
michael@0 165 uint16_t mAnimationMode;
michael@0 166
michael@0 167 //! Whether this image is done being decoded.
michael@0 168 bool mDoneDecoding;
michael@0 169 };
michael@0 170
michael@0 171 } // namespace image
michael@0 172 } // namespace mozilla
michael@0 173
michael@0 174 #endif /* mozilla_imagelib_FrameAnimator_h_ */

mercurial