Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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_FrameBlender_h_ |
michael@0 | 8 | #define mozilla_imagelib_FrameBlender_h_ |
michael@0 | 9 | |
michael@0 | 10 | #include "mozilla/MemoryReporting.h" |
michael@0 | 11 | #include "gfxTypes.h" |
michael@0 | 12 | #include "FrameSequence.h" |
michael@0 | 13 | #include "nsCOMPtr.h" |
michael@0 | 14 | |
michael@0 | 15 | class imgFrame; |
michael@0 | 16 | |
michael@0 | 17 | namespace mozilla { |
michael@0 | 18 | namespace image { |
michael@0 | 19 | |
michael@0 | 20 | /** |
michael@0 | 21 | * FrameBlender stores and gives access to imgFrames. It also knows how to |
michael@0 | 22 | * blend frames from previous to next, looping if necessary. |
michael@0 | 23 | * |
michael@0 | 24 | * All logic about when and whether to blend are external to FrameBlender. |
michael@0 | 25 | */ |
michael@0 | 26 | class FrameBlender |
michael@0 | 27 | { |
michael@0 | 28 | public: |
michael@0 | 29 | |
michael@0 | 30 | /** |
michael@0 | 31 | * Create a new FrameBlender with a given frame sequence. |
michael@0 | 32 | * |
michael@0 | 33 | * If aSequenceToUse is not specified, it will be allocated automatically. |
michael@0 | 34 | */ |
michael@0 | 35 | FrameBlender(FrameSequence* aSequenceToUse = nullptr); |
michael@0 | 36 | ~FrameBlender(); |
michael@0 | 37 | |
michael@0 | 38 | bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex, |
michael@0 | 39 | uint32_t aNextFrameIndex); |
michael@0 | 40 | |
michael@0 | 41 | already_AddRefed<FrameSequence> GetFrameSequence(); |
michael@0 | 42 | |
michael@0 | 43 | /** |
michael@0 | 44 | * Get the @aIndex-th frame, including (if applicable) any results of |
michael@0 | 45 | * blending. |
michael@0 | 46 | */ |
michael@0 | 47 | imgFrame* GetFrame(uint32_t aIndex) const; |
michael@0 | 48 | |
michael@0 | 49 | /** |
michael@0 | 50 | * Get the @aIndex-th frame in the frame index, ignoring results of blending. |
michael@0 | 51 | */ |
michael@0 | 52 | imgFrame* RawGetFrame(uint32_t aIndex) const; |
michael@0 | 53 | |
michael@0 | 54 | void InsertFrame(uint32_t framenum, imgFrame* aFrame); |
michael@0 | 55 | void RemoveFrame(uint32_t framenum); |
michael@0 | 56 | imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame); |
michael@0 | 57 | void ClearFrames(); |
michael@0 | 58 | |
michael@0 | 59 | /* The total number of frames in this image. */ |
michael@0 | 60 | uint32_t GetNumFrames() const; |
michael@0 | 61 | |
michael@0 | 62 | /* |
michael@0 | 63 | * Returns the frame's adjusted timeout. If the animation loops and the timeout |
michael@0 | 64 | * falls in between a certain range then the timeout is adjusted so that |
michael@0 | 65 | * it's never 0. If the animation does not loop then no adjustments are made. |
michael@0 | 66 | */ |
michael@0 | 67 | int32_t GetTimeoutForFrame(uint32_t framenum) const; |
michael@0 | 68 | |
michael@0 | 69 | /* |
michael@0 | 70 | * Set number of times to loop the image. |
michael@0 | 71 | * @note -1 means loop forever. |
michael@0 | 72 | */ |
michael@0 | 73 | void SetLoopCount(int32_t aLoopCount); |
michael@0 | 74 | int32_t GetLoopCount() const; |
michael@0 | 75 | |
michael@0 | 76 | void Discard(); |
michael@0 | 77 | |
michael@0 | 78 | void SetSize(nsIntSize aSize) { mSize = aSize; } |
michael@0 | 79 | |
michael@0 | 80 | size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation, |
michael@0 | 81 | mozilla::MallocSizeOf aMallocSizeOf) const; |
michael@0 | 82 | |
michael@0 | 83 | void ResetAnimation(); |
michael@0 | 84 | |
michael@0 | 85 | // "Blend" method indicates how the current image is combined with the |
michael@0 | 86 | // previous image. |
michael@0 | 87 | enum FrameBlendMethod { |
michael@0 | 88 | // All color components of the frame, including alpha, overwrite the current |
michael@0 | 89 | // contents of the frame's output buffer region |
michael@0 | 90 | kBlendSource = 0, |
michael@0 | 91 | |
michael@0 | 92 | // The frame should be composited onto the output buffer based on its alpha, |
michael@0 | 93 | // using a simple OVER operation |
michael@0 | 94 | kBlendOver |
michael@0 | 95 | }; |
michael@0 | 96 | |
michael@0 | 97 | enum FrameDisposalMethod { |
michael@0 | 98 | kDisposeClearAll = -1, // Clear the whole image, revealing |
michael@0 | 99 | // what was there before the gif displayed |
michael@0 | 100 | kDisposeNotSpecified, // Leave frame, let new frame draw on top |
michael@0 | 101 | kDisposeKeep, // Leave frame, let new frame draw on top |
michael@0 | 102 | kDisposeClear, // Clear the frame's area, revealing bg |
michael@0 | 103 | kDisposeRestorePrevious // Restore the previous (composited) frame |
michael@0 | 104 | }; |
michael@0 | 105 | |
michael@0 | 106 | // A hint as to whether an individual frame is entirely opaque, or requires |
michael@0 | 107 | // alpha blending. |
michael@0 | 108 | enum FrameAlpha { |
michael@0 | 109 | kFrameHasAlpha, |
michael@0 | 110 | kFrameOpaque |
michael@0 | 111 | }; |
michael@0 | 112 | |
michael@0 | 113 | private: |
michael@0 | 114 | |
michael@0 | 115 | struct Anim |
michael@0 | 116 | { |
michael@0 | 117 | //! Track the last composited frame for Optimizations (See DoComposite code) |
michael@0 | 118 | int32_t lastCompositedFrameIndex; |
michael@0 | 119 | |
michael@0 | 120 | /** For managing blending of frames |
michael@0 | 121 | * |
michael@0 | 122 | * Some animations will use the compositingFrame to composite images |
michael@0 | 123 | * and just hand this back to the caller when it is time to draw the frame. |
michael@0 | 124 | * NOTE: When clearing compositingFrame, remember to set |
michael@0 | 125 | * lastCompositedFrameIndex to -1. Code assume that if |
michael@0 | 126 | * lastCompositedFrameIndex >= 0 then compositingFrame exists. |
michael@0 | 127 | */ |
michael@0 | 128 | FrameDataPair compositingFrame; |
michael@0 | 129 | |
michael@0 | 130 | /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS |
michael@0 | 131 | * |
michael@0 | 132 | * The Previous Frame (all frames composited up to the current) needs to be |
michael@0 | 133 | * stored in cases where the image specifies it wants the last frame back |
michael@0 | 134 | * when it's done with the current frame. |
michael@0 | 135 | */ |
michael@0 | 136 | FrameDataPair compositingPrevFrame; |
michael@0 | 137 | |
michael@0 | 138 | Anim() : |
michael@0 | 139 | lastCompositedFrameIndex(-1) |
michael@0 | 140 | {} |
michael@0 | 141 | }; |
michael@0 | 142 | |
michael@0 | 143 | void EnsureAnimExists(); |
michael@0 | 144 | |
michael@0 | 145 | /** Clears an area of <aFrame> with transparent black. |
michael@0 | 146 | * |
michael@0 | 147 | * @param aFrameData Target Frame data |
michael@0 | 148 | * @param aFrameRect The rectangle of the data pointed ot by aFrameData |
michael@0 | 149 | * |
michael@0 | 150 | * @note Does also clears the transparancy mask |
michael@0 | 151 | */ |
michael@0 | 152 | static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect); |
michael@0 | 153 | |
michael@0 | 154 | //! @overload |
michael@0 | 155 | static void ClearFrame(uint8_t* aFrameData, const nsIntRect& aFrameRect, const nsIntRect &aRectToClear); |
michael@0 | 156 | |
michael@0 | 157 | //! Copy one frames's image and mask into another |
michael@0 | 158 | static bool CopyFrameImage(const uint8_t *aDataSrc, const nsIntRect& aRectSrc, |
michael@0 | 159 | uint8_t *aDataDest, const nsIntRect& aRectDest); |
michael@0 | 160 | |
michael@0 | 161 | /** |
michael@0 | 162 | * Draws one frames's image to into another, at the position specified by |
michael@0 | 163 | * aSrcRect. |
michael@0 | 164 | * |
michael@0 | 165 | * @aSrcData the raw data of the current frame being drawn |
michael@0 | 166 | * @aSrcRect the size of the source frame, and the position of that frame in |
michael@0 | 167 | * the composition frame |
michael@0 | 168 | * @aSrcPaletteLength the length (in bytes) of the palette at the beginning |
michael@0 | 169 | * of the source data (0 if image is not paletted) |
michael@0 | 170 | * @aSrcHasAlpha whether the source data represents an image with alpha |
michael@0 | 171 | * @aDstPixels the raw data of the composition frame where the current frame |
michael@0 | 172 | * is drawn into (32-bit ARGB) |
michael@0 | 173 | * @aDstRect the size of the composition frame |
michael@0 | 174 | * @aBlendMethod the blend method for how to blend src on the composition frame. |
michael@0 | 175 | */ |
michael@0 | 176 | static nsresult DrawFrameTo(const uint8_t *aSrcData, const nsIntRect& aSrcRect, |
michael@0 | 177 | uint32_t aSrcPaletteLength, bool aSrcHasAlpha, |
michael@0 | 178 | uint8_t *aDstPixels, const nsIntRect& aDstRect, |
michael@0 | 179 | FrameBlendMethod aBlendMethod); |
michael@0 | 180 | |
michael@0 | 181 | private: // data |
michael@0 | 182 | //! All the frames of the image |
michael@0 | 183 | nsRefPtr<FrameSequence> mFrames; |
michael@0 | 184 | nsIntSize mSize; |
michael@0 | 185 | Anim* mAnim; |
michael@0 | 186 | int32_t mLoopCount; |
michael@0 | 187 | }; |
michael@0 | 188 | |
michael@0 | 189 | } // namespace image |
michael@0 | 190 | } // namespace mozilla |
michael@0 | 191 | |
michael@0 | 192 | #endif /* mozilla_imagelib_FrameBlender_h_ */ |