diff options
-rw-r--r-- | image/AnimationParams.h | 45 | ||||
-rw-r--r-- | image/imgFrame.cpp | 39 | ||||
-rw-r--r-- | image/imgFrame.h | 72 |
3 files changed, 91 insertions, 65 deletions
diff --git a/image/AnimationParams.h b/image/AnimationParams.h new file mode 100644 index 000000000..916ba7e40 --- /dev/null +++ b/image/AnimationParams.h @@ -0,0 +1,45 @@ +/* -*- 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/. */ + +#ifndef mozilla_image_AnimationParams_h +#define mozilla_image_AnimationParams_h + +#include <stdint.h> +#include "mozilla/gfx/Rect.h" +#include "FrameTimeout.h" + +namespace mozilla { +namespace image { + +enum class BlendMethod : int8_t { + // All color components of the frame, including alpha, overwrite the current + // contents of the frame's output buffer region. + SOURCE, + + // The frame should be composited onto the output buffer based on its alpha, + // using a simple OVER operation. + OVER +}; + +enum class DisposalMethod : int8_t { + CLEAR_ALL = -1, // Clear the whole image, revealing what's underneath. + NOT_SPECIFIED, // Leave the frame and let the new frame draw on top. + KEEP, // Leave the frame and let the new frame draw on top. + CLEAR, // Clear the frame's area, revealing what's underneath. + RESTORE_PREVIOUS // Restore the previous (composited) frame. +}; + +struct AnimationParams +{ + gfx::IntRect mBlendRect; + FrameTimeout mTimeout; + uint32_t mFrameNum; + BlendMethod mBlendMethod; + DisposalMethod mDisposalMethod; +}; + +} // namespace image +} // namespace mozilla diff --git a/image/imgFrame.cpp b/image/imgFrame.cpp index 5da2ccec5..af84d8cbb 100644 --- a/image/imgFrame.cpp +++ b/image/imgFrame.cpp @@ -161,13 +161,13 @@ imgFrame::imgFrame() : mMonitor("imgFrame") , mDecoded(0, 0, 0, 0) , mLockCount(0) + , mAborted(false) + , mFinished(false) + , mOptimizable(false) , mTimeout(FrameTimeout::FromRawMilliseconds(100)) , mDisposalMethod(DisposalMethod::NOT_SPECIFIED) , mBlendMethod(BlendMethod::OVER) , mHasNoAlpha(false) - , mAborted(false) - , mFinished(false) - , mOptimizable(false) , mPalettedImageData(nullptr) , mPaletteDepth(0) , mNonPremult(false) @@ -192,7 +192,8 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, const nsIntRect& aRect, SurfaceFormat aFormat, uint8_t aPaletteDepth /* = 0 */, - bool aNonPremult /* = false */) + bool aNonPremult /* = false */, + const Maybe<AnimationParams>& aAnimParams /* = Nothing() */) { // Assert for properties that should be verified by decoders, // warn for properties related to bad content. @@ -205,6 +206,15 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, mImageSize = aImageSize; mFrameRect = aRect; + if (aAnimParams) { + mBlendRect = aAnimParams->mBlendRect; + mTimeout = aAnimParams->mTimeout; + mBlendMethod = aAnimParams->mBlendMethod; + mDisposalMethod = aAnimParams->mDisposalMethod; + } else { + mBlendRect = aRect; + } + // We only allow a non-trivial frame rect (i.e., a frame rect that doesn't // cover the entire image) for paletted animation frames. We never draw those // frames directly; we just use FrameAnimator to composite them and produce a @@ -242,13 +252,13 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, } else { MOZ_ASSERT(!mImageSurface, "Called imgFrame::InitForDecoder() twice?"); - mVBuf = AllocateBufferForImage(mFrameRect.Size(), mFormat); - if (!mVBuf) { + mRawSurface = AllocateBufferForImage(mFrameRect.Size(), mFormat); + if (!mRawSurface) { mAborted = true; return NS_ERROR_OUT_OF_MEMORY; } - mImageSurface = CreateLockedSurface(mVBuf, mFrameRect.Size(), mFormat); + mImageSurface = CreateLockedSurface(mRawSurface, mFrameRect.Size(), mFormat); if (!mImageSurface) { NS_WARNING("Failed to create ImageSurface"); @@ -256,7 +266,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize, return NS_ERROR_OUT_OF_MEMORY; } - if (!ClearSurface(mVBuf, mFrameRect.Size(), mFormat)) { + if (!ClearSurface(mRawSurface, mFrameRect.Size(), mFormat)) { NS_WARNING("Could not clear allocated buffer"); mAborted = true; return NS_ERROR_OUT_OF_MEMORY; @@ -607,12 +617,7 @@ imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) } void -imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */, - DisposalMethod aDisposalMethod /* = DisposalMethod::KEEP */, - FrameTimeout aTimeout - /* = FrameTimeout::FromRawMilliseconds(0) */, - BlendMethod aBlendMethod /* = BlendMethod::OVER */, - const Maybe<IntRect>& aBlendRect /* = Nothing() */) +imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */) { MonitorAutoLock lock(mMonitor); MOZ_ASSERT(mLockCount > 0, "Image data should be locked"); @@ -621,10 +626,6 @@ imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */, mHasNoAlpha = true; } - mDisposalMethod = aDisposalMethod; - mTimeout = aTimeout; - mBlendMethod = aBlendMethod; - mBlendRect = aBlendRect; ImageUpdatedInternal(GetRect()); mFinished = true; @@ -844,7 +845,7 @@ imgFrame::GetAnimationData() const bool hasAlpha = mFormat == SurfaceFormat::B8G8R8A8; return AnimationData(data, PaletteDataLength(), mTimeout, GetRect(), - mBlendMethod, mBlendRect, mDisposalMethod, hasAlpha); + mBlendMethod, Some(mBlendRect), mDisposalMethod, hasAlpha); } void diff --git a/image/imgFrame.h b/image/imgFrame.h index e864aca7f..32aabacae 100644 --- a/image/imgFrame.h +++ b/image/imgFrame.h @@ -12,6 +12,7 @@ #include "mozilla/Monitor.h" #include "mozilla/Move.h" #include "mozilla/VolatileBuffer.h" +#include "AnimationParams.h" #include "gfxDrawable.h" #include "imgIContainer.h" #include "MainThreadUtils.h" @@ -23,24 +24,6 @@ class ImageRegion; class DrawableFrameRef; class RawAccessFrameRef; -enum class BlendMethod : int8_t { - // All color components of the frame, including alpha, overwrite the current - // contents of the frame's output buffer region. - SOURCE, - - // The frame should be composited onto the output buffer based on its alpha, - // using a simple OVER operation. - OVER -}; - -enum class DisposalMethod : int8_t { - CLEAR_ALL = -1, // Clear the whole image, revealing what's underneath. - NOT_SPECIFIED, // Leave the frame and let the new frame draw on top. - KEEP, // Leave the frame and let the new frame draw on top. - CLEAR, // Clear the frame's area, revealing what's underneath. - RESTORE_PREVIOUS // Restore the previous (composited) frame. -}; - enum class Opacity : uint8_t { FULLY_OPAQUE, SOME_TRANSPARENCY @@ -210,14 +193,19 @@ public: const nsIntRect& aRect, SurfaceFormat aFormat, uint8_t aPaletteDepth = 0, - bool aNonPremult = false); + bool aNonPremult = false, + const Maybe<AnimationParams>& aAnimParams = Nothing()); nsresult InitForDecoder(const nsIntSize& aSize, SurfaceFormat aFormat, uint8_t aPaletteDepth = 0) { - return InitForDecoder(aSize, nsIntRect(0, 0, aSize.width, aSize.height), - aFormat, aPaletteDepth); + nsIntRect frameRect(0, 0, aSize.width, aSize.height); + AnimationParams animParams { frameRect, FrameTimeout::Forever(), + /* aFrameNum */ 1, BlendMethod::OVER, + DisposalMethod::NOT_SPECIFIED }; + return InitForDecoder(aSize, frameRect, + aFormat, aPaletteDepth, false, Some(animParams)); } @@ -268,22 +256,8 @@ public: * RawAccessFrameRef pointing to an imgFrame. * * @param aFrameOpacity Whether this imgFrame is opaque. - * @param aDisposalMethod For animation frames, how this imgFrame is cleared - * from the compositing frame before the next frame is - * displayed. - * @param aTimeout For animation frames, the timeout before the next - * frame is displayed. - * @param aBlendMethod For animation frames, a blending method to be used - * when compositing this frame. - * @param aBlendRect For animation frames, if present, the subrect in - * which @aBlendMethod applies. Outside of this - * subrect, BlendMethod::OVER is always used. */ - void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY, - DisposalMethod aDisposalMethod = DisposalMethod::KEEP, - FrameTimeout aTimeout = FrameTimeout::FromRawMilliseconds(0), - BlendMethod aBlendMethod = BlendMethod::OVER, - const Maybe<IntRect>& aBlendRect = Nothing()); + void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY); /** * Mark this imgFrame as aborted. This informs the imgFrame that if it isn't @@ -322,9 +296,15 @@ public: */ uint32_t GetBytesPerPixel() const { return GetIsPaletted() ? 1 : 4; } - IntSize GetImageSize() const { return mImageSize; } - IntRect GetRect() const { return mFrameRect; } + const IntSize& GetImageSize() const { return mImageSize; } + const IntRect& GetRect() const { return mFrameRect; } IntSize GetSize() const { return mFrameRect.Size(); } + const IntRect& GetBlendRect() const { return mBlendRect; } + IntRect GetBoundedBlendRect() const { return mBlendRect.Intersect(mFrameRect); } + FrameTimeout GetTimeout() const { return mTimeout; } + BlendMethod GetBlendMethod() const { return mBlendMethod; } + DisposalMethod GetDisposalMethod() const { return mDisposalMethod; } + bool FormatHasAlpha() const { return mFormat == SurfaceFormat::B8G8R8A8; } void GetImageData(uint8_t** aData, uint32_t* length) const; uint8_t* GetImageData() const; @@ -406,14 +386,6 @@ private: // data //! Number of RawAccessFrameRefs currently alive for this imgFrame. int32_t mLockCount; - //! The timeout for this frame. - FrameTimeout mTimeout; - - DisposalMethod mDisposalMethod; - BlendMethod mBlendMethod; - Maybe<IntRect> mBlendRect; - SurfaceFormat mFormat; - bool mHasNoAlpha; bool mAborted; bool mFinished; @@ -426,6 +398,14 @@ private: // data IntSize mImageSize; IntRect mFrameRect; + IntRect mBlendRect; + + //! The timeout for this frame. + FrameTimeout mTimeout; + + DisposalMethod mDisposalMethod; + BlendMethod mBlendMethod; + SurfaceFormat mFormat; // The palette and image data for images that are paletted, since Cairo // doesn't support these images. |