author | Andi-Bogdan Postelnicu <bpostelnicu@mozilla.com> |
Mon, 04 Jan 2021 14:20:22 +0000 | |
changeset 561874 | fd6a14bb471409ecab18b712d5aa053a22a4f02b |
parent 561873 | 94098bf0178be3135cb6e7b38cf32da0d98cdf90 |
child 561875 | 46b6574bdfa0ce71941aba81196033558b7d6080 |
push id | 38075 |
push user | dluca@mozilla.com |
push date | Tue, 05 Jan 2021 04:31:31 +0000 |
treeherder | mozilla-central@1d89f3cb5bb3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | aosmond |
bugs | 1683557 |
milestone | 86.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/build/non-unified-compat +++ b/build/non-unified-compat @@ -101,8 +101,9 @@ gfx/tests/ gfx/thebes/ gfx/vr/ gfx/webrender_bindings/ gfx/wgpu/ gfx/wgpu_bindings/ gfx/wr/ gfx/ycbcr/ hal/ +image/
--- a/image/Decoder.cpp +++ b/image/Decoder.cpp @@ -4,16 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Decoder.h" #include "DecodePool.h" #include "GeckoProfiler.h" #include "IDecodingTask.h" #include "ISurfaceProvider.h" +#include "gfxPlatform.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Point.h" #include "mozilla/Telemetry.h" #include "nsComponentManagerUtils.h" #include "nsProxyRelease.h" #include "nsServiceManagerUtils.h" using mozilla::gfx::IntPoint;
--- a/image/FrameAnimator.cpp +++ b/image/FrameAnimator.cpp @@ -1,14 +1,15 @@ /* -*- 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/. */ #include "FrameAnimator.h" +#include "GeckoProfiler.h" #include <utility> #include "LookupResult.h" #include "RasterImage.h" #include "imgIContainer.h" #include "mozilla/CheckedInt.h" #include "mozilla/StaticPrefs_image.h"
--- a/image/Image.cpp +++ b/image/Image.cpp @@ -5,16 +5,18 @@ #include "Image.h" #include "imgRequest.h" #include "Layers.h" // for LayerManager #include "nsIObserverService.h" #include "nsRefreshDriver.h" #include "nsContentUtils.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/gfx/Rect.h" #include "mozilla/Services.h" #include "mozilla/SizeOfState.h" #include "mozilla/TimeStamp.h" #include "mozilla/Tuple.h" // for Tie #include "mozilla/layers/SharedSurfacesChild.h" namespace mozilla { namespace image { @@ -101,19 +103,19 @@ bool ImageResource::GetSpecTruncatedTo1k if (sMaxTruncatedLength >= aSpec.Length()) { return true; } aSpec.Truncate(sMaxTruncatedLength); return false; } -void ImageResource::SetCurrentImage(ImageContainer* aContainer, - SourceSurface* aSurface, - const Maybe<IntRect>& aDirtyRect) { +void ImageResource::SetCurrentImage(layers::ImageContainer* aContainer, + gfx::SourceSurface* aSurface, + const Maybe<gfx::IntRect>& aDirtyRect) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aContainer); if (!aSurface) { // The OS threw out some or all of our buffer. We'll need to wait for the // redecode (which was automatically triggered by GetFrame) to complete. return; } @@ -123,54 +125,54 @@ void ImageResource::SetCurrentImage(Imag // long as the layer system keeps this ImageContainer alive. RefPtr<layers::Image> image = new layers::SourceSurfaceImage(aSurface); // We can share the producer ID with other containers because it is only // used internally to validate the frames given to a particular container // so that another object cannot add its own. Similarly the frame ID is // only used internally to ensure it is always increasing, and skipping // IDs from an individual container's perspective is acceptable. - AutoTArray<ImageContainer::NonOwningImage, 1> imageList; - imageList.AppendElement(ImageContainer::NonOwningImage( + AutoTArray<layers::ImageContainer::NonOwningImage, 1> imageList; + imageList.AppendElement(layers::ImageContainer::NonOwningImage( image, TimeStamp(), mLastFrameID++, mImageProducerID)); if (aDirtyRect) { aContainer->SetCurrentImagesInTransaction(imageList); } else { aContainer->SetCurrentImages(imageList); } // If we are animated, then we should request that the image container be // treated as such, to avoid display list rebuilding to update frames for // WebRender. if (mProgressTracker->GetProgress() & FLAG_IS_ANIMATED) { if (aDirtyRect) { layers::SharedSurfacesChild::UpdateAnimation(aContainer, aSurface, aDirtyRect.ref()); } else { - IntRect dirtyRect(IntPoint(0, 0), aSurface->GetSize()); + gfx::IntRect dirtyRect(gfx::IntPoint(0, 0), aSurface->GetSize()); layers::SharedSurfacesChild::UpdateAnimation(aContainer, aSurface, dirtyRect); } } } ImgDrawResult ImageResource::GetImageContainerImpl( - LayerManager* aManager, const IntSize& aSize, + layers::LayerManager* aManager, const gfx::IntSize& aSize, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags, - ImageContainer** aOutContainer) { + layers::ImageContainer** aOutContainer) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aManager); MOZ_ASSERT( (aFlags & ~(FLAG_SYNC_DECODE | FLAG_SYNC_DECODE_IF_FAST | FLAG_ASYNC_NOTIFY | FLAG_HIGH_QUALITY_SCALING)) == FLAG_NONE, "Unsupported flag passed to GetImageContainer"); ImgDrawResult drawResult; - IntSize size; + gfx::IntSize size; Tie(drawResult, size) = GetImageContainerSize(aManager, aSize, aFlags); if (drawResult != ImgDrawResult::SUCCESS) { return drawResult; } MOZ_ASSERT(!size.IsEmpty()); if (mAnimationConsumers == 0) { @@ -216,18 +218,18 @@ ImgDrawResult ImageResource::GetImageCon return entry->mLastDrawResult; } } #ifdef DEBUG NotifyDrawingObservers(); #endif - IntSize bestSize; - RefPtr<SourceSurface> surface; + gfx::IntSize bestSize; + RefPtr<gfx::SourceSurface> surface; Tie(drawResult, bestSize, surface) = GetFrameInternal( size, aSVGContext, FRAME_CURRENT, aFlags | FLAG_ASYNC_NOTIFY); // The requested size might be refused by the surface cache (i.e. due to // factor-of-2 mode). In that case we don't want to create an entry for this // specific size, but rather re-use the entry for the substituted size. if (bestSize != size) { MOZ_ASSERT(!bestSize.IsEmpty()); @@ -277,52 +279,53 @@ ImgDrawResult ImageResource::GetImageCon } break; } } } if (!container) { // We need a new ImageContainer, so create one. - container = LayerManager::CreateImageContainer(); + container = layers::LayerManager::CreateImageContainer(); if (i >= 0) { entry->mContainer = container; } else { entry = mImageContainers.AppendElement( ImageContainerEntry(bestSize, aSVGContext, container.get(), flags)); } } SetCurrentImage(container, surface, Nothing()); entry->mLastDrawResult = drawResult; container.forget(aOutContainer); return drawResult; } -bool ImageResource::UpdateImageContainer(const Maybe<IntRect>& aDirtyRect) { +bool ImageResource::UpdateImageContainer( + const Maybe<gfx::IntRect>& aDirtyRect) { MOZ_ASSERT(NS_IsMainThread()); for (int i = mImageContainers.Length() - 1; i >= 0; --i) { ImageContainerEntry& entry = mImageContainers[i]; RefPtr<layers::ImageContainer> container(entry.mContainer); if (container) { - IntSize bestSize; - RefPtr<SourceSurface> surface; + gfx::IntSize bestSize; + RefPtr<gfx::SourceSurface> surface; Tie(entry.mLastDrawResult, bestSize, surface) = GetFrameInternal( entry.mSize, entry.mSVGContext, FRAME_CURRENT, entry.mFlags); // It is possible that this is a factor-of-2 substitution. Since we // managed to convert the weak reference into a strong reference, that // means that an imagelib user still is holding onto the container. thus // we cannot consolidate and must keep updating the duplicate container. if (aDirtyRect) { SetCurrentImage(container, surface, aDirtyRect); } else { - IntRect dirtyRect(IntPoint(0, 0), bestSize); + gfx::IntRect dirtyRect(gfx::IntPoint(0, 0), bestSize); SetCurrentImage(container, surface, Some(dirtyRect)); } } else { // Stop tracking if our weak pointer to the image container was freed. mImageContainers.RemoveElementAt(i); } } @@ -338,17 +341,17 @@ void ImageResource::ReleaseImageContaine ImageResource::ImageResource(nsIURI* aURI) : mURI(aURI), mInnerWindowId(0), mAnimationConsumers(0), mAnimationMode(kNormalAnimMode), mInitialized(false), mAnimating(false), mError(false), - mImageProducerID(ImageContainer::AllocateProducerID()), + mImageProducerID(layers::ImageContainer::AllocateProducerID()), mLastFrameID(0) {} ImageResource::~ImageResource() { // Ask our ProgressTracker to drop its weak reference to us. mProgressTracker->ResetImage(); } void ImageResource::IncrementAnimationConsumers() {
--- a/image/ImageFactory.cpp +++ b/image/ImageFactory.cpp @@ -5,17 +5,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ImageFactory.h" #include <algorithm> #include "mozilla/Likely.h" +#include "nsIChannel.h" #include "nsIFileChannel.h" +#include "nsIObserverService.h" #include "nsIFile.h" #include "nsMimeTypes.h" #include "nsIRequest.h" #include "MultipartImage.h" #include "RasterImage.h" #include "VectorImage.h" #include "Image.h"
--- a/image/ImageRegion.h +++ b/image/ImageRegion.h @@ -2,18 +2,22 @@ /* 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_ImageRegion_h #define mozilla_image_ImageRegion_h #include "gfxMatrix.h" +#include "gfxPoint.h" #include "gfxRect.h" +#include "gfxTypes.h" +#include "mozilla/gfx/Matrix.h" #include "mozilla/gfx/Types.h" +#include "nsSize.h" namespace mozilla { namespace image { /** * An axis-aligned rectangle in tiled image space, with an optional sampling * restriction rect. The drawing code ensures that if a sampling restriction * rect is present, any pixels sampled during the drawing process are found
--- a/image/SVGDocumentWrapper.cpp +++ b/image/SVGDocumentWrapper.cpp @@ -3,16 +3,17 @@ * 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/. */ #include "SVGDocumentWrapper.h" #include "mozilla/PresShell.h" #include "mozilla/SMILAnimationController.h" #include "mozilla/SVGObserverUtils.h" +#include "mozilla/dom/Animation.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/DocumentTimeline.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/dom/SVGDocument.h" #include "mozilla/dom/SVGSVGElement.h" #include "nsICategoryManager.h" #include "nsIChannel.h"
--- a/image/SurfaceCache.cpp +++ b/image/SurfaceCache.cpp @@ -30,16 +30,17 @@ #include "mozilla/StaticPtr.h" #include "mozilla/Tuple.h" #include "nsExpirationTracker.h" #include "nsHashKeys.h" #include "nsIMemoryReporter.h" #include "nsRefPtrHashtable.h" #include "nsSize.h" #include "nsTArray.h" +#include "Orientation.h" #include "prsystem.h" using std::max; using std::min; namespace mozilla { using namespace gfx;
--- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -1,29 +1,31 @@ /* -*- 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/. */ #include "VectorImage.h" +#include "GeckoProfiler.h" #include "gfx2DGlue.h" #include "gfxContext.h" #include "gfxDrawable.h" #include "gfxPlatform.h" #include "gfxUtils.h" #include "imgFrame.h" #include "mozilla/AutoRestore.h" #include "mozilla/MemoryReporting.h" #include "mozilla/MediaFeatureChange.h" #include "mozilla/dom/Event.h" #include "mozilla/dom/SVGSVGElement.h" #include "mozilla/dom/SVGDocument.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/gfxVars.h" +#include "mozilla/layers/LayerManager.h" #include "mozilla/PendingAnimationTracker.h" #include "mozilla/PresShell.h" #include "mozilla/RefPtr.h" #include "mozilla/SVGObserverUtils.h" // for SVGRenderingObserver #include "mozilla/Tuple.h" #include "nsIStreamListener.h" #include "nsMimeTypes.h" #include "nsPresContext.h"
--- a/image/VectorImage.h +++ b/image/VectorImage.h @@ -3,16 +3,17 @@ * 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_VectorImage_h #define mozilla_image_VectorImage_h #include "Image.h" #include "nsIStreamListener.h" +#include "mozilla/gfx/Point.h" #include "mozilla/MemoryReporting.h" class nsIRequest; class gfxDrawable; namespace mozilla { struct MediaFeatureChange; @@ -74,44 +75,45 @@ class VectorImage final : public ImageRe explicit VectorImage(nsIURI* aURI = nullptr); virtual ~VectorImage(); virtual nsresult StartAnimation() override; virtual nsresult StopAnimation() override; virtual bool ShouldAnimate() override; private: - Tuple<ImgDrawResult, IntSize, RefPtr<SourceSurface>> GetFrameInternal( - const IntSize& aSize, const Maybe<SVGImageContext>& aSVGContext, - uint32_t aWhichFrame, uint32_t aFlags) override; + Tuple<ImgDrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>> + GetFrameInternal(const gfx::IntSize& aSize, + const Maybe<SVGImageContext>& aSVGContext, + uint32_t aWhichFrame, uint32_t aFlags) override; - Tuple<ImgDrawResult, IntSize> GetImageContainerSize( - layers::LayerManager* aManager, const IntSize& aSize, + Tuple<ImgDrawResult, gfx::IntSize> GetImageContainerSize( + layers::LayerManager* aManager, const gfx::IntSize& aSize, uint32_t aFlags) override; /** * Attempt to find a matching cached surface in the SurfaceCache. Returns the * cached surface, if found, and the size to rasterize at, if applicable. * If we cannot rasterize, it will be the requested size to draw at (aSize). */ - Tuple<RefPtr<SourceSurface>, IntSize> LookupCachedSurface( - const IntSize& aSize, const Maybe<SVGImageContext>& aSVGContext, + Tuple<RefPtr<gfx::SourceSurface>, gfx::IntSize> LookupCachedSurface( + const gfx::IntSize& aSize, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags); bool MaybeRestrictSVGContext(Maybe<SVGImageContext>& aNewSVGContext, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags); /// Create a gfxDrawable which callbacks into the SVG document. already_AddRefed<gfxDrawable> CreateSVGDrawable( const SVGDrawingParameters& aParams); /// Rasterize the SVG into a surface. aWillCache will be set to whether or /// not the new surface was put into the cache. - already_AddRefed<SourceSurface> CreateSurface( + already_AddRefed<gfx::SourceSurface> CreateSurface( const SVGDrawingParameters& aParams, gfxDrawable* aSVGDrawable, bool& aWillCache); /// Send a frame complete notification if appropriate. Must be called only /// after all drawing has been completed. void SendFrameComplete(bool aDidCache, uint32_t aFlags); void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);
--- a/image/decoders/icon/nsIconURI.h +++ b/image/decoders/icon/nsIconURI.h @@ -7,16 +7,17 @@ #ifndef mozilla_image_decoders_icon_nsIconURI_h #define mozilla_image_decoders_icon_nsIconURI_h #include "nsIIconURI.h" #include "nsCOMPtr.h" #include "nsString.h" #include "nsINestedURI.h" #include "nsIURIMutator.h" +#include "nsISerializable.h" #define NS_THIS_ICONURI_IMPLEMENTATION_CID \ { /* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */ \ 0x5c3e417f, 0xb686, 0x4105, { \ 0x86, 0xe7, 0xf9, 0x1b, 0xac, 0x97, 0x4d, 0x5c \ } \ }
--- a/image/decoders/nsGIFDecoder2.h +++ b/image/decoders/nsGIFDecoder2.h @@ -151,16 +151,16 @@ class nsGIFDecoder2 : public Decoder { uint32_t mColormapSize; uint8_t mColorMask; // Apply this to the pixel to keep within colormap bool mGIFOpen; bool mSawTransparency; gif_struct mGIFStruct; - SwizzleRowFn mSwizzleFn; /// Method to unpack color tables from RGB. + gfx::SwizzleRowFn mSwizzleFn; /// Method to unpack color tables from RGB. SurfacePipe mPipe; /// The SurfacePipe used to write to the output surface. }; } // namespace image } // namespace mozilla #endif // mozilla_image_decoders_nsGIFDecoder2_h
--- a/image/decoders/nsIconDecoder.cpp +++ b/image/decoders/nsIconDecoder.cpp @@ -2,16 +2,17 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */ #include "nsIconDecoder.h" #include "RasterImage.h" #include "SurfacePipeFactory.h" +#include "gfxPlatform.h" using namespace mozilla::gfx; namespace mozilla { namespace image { static const uint32_t ICON_HEADER_SIZE = 4;
--- a/image/decoders/nsJPEGDecoder.cpp +++ b/image/decoders/nsJPEGDecoder.cpp @@ -926,14 +926,15 @@ static void cmyk_convert_bgra(uint32_t* const uint32_t iM = input[1]; const uint32_t iY = input[2]; const uint32_t iK = input[3]; const uint8_t r = iC * iK / 255; const uint8_t g = iM * iK / 255; const uint8_t b = iY * iK / 255; - *aOutput++ = (0xFF << SurfaceFormatBit::OS_A) | - (r << SurfaceFormatBit::OS_R) | (g << SurfaceFormatBit::OS_G) | - (b << SurfaceFormatBit::OS_B); + *aOutput++ = (0xFF << mozilla::gfx::SurfaceFormatBit::OS_A) | + (r << mozilla::gfx::SurfaceFormatBit::OS_R) | + (g << mozilla::gfx::SurfaceFormatBit::OS_G) | + (b << mozilla::gfx::SurfaceFormatBit::OS_B); input += 4; } }
--- a/image/decoders/nsWebPDecoder.cpp +++ b/image/decoders/nsWebPDecoder.cpp @@ -1,15 +1,17 @@ /* -*- 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/. */ #include "ImageLogging.h" // Must appear first +#include "gfxPlatform.h" +#include "mozilla/TelemetryHistogramEnums.h" #include "nsWebPDecoder.h" #include "RasterImage.h" #include "SurfacePipeFactory.h" using namespace mozilla::gfx; namespace mozilla {
--- a/image/decoders/nsWebPDecoder.h +++ b/image/decoders/nsWebPDecoder.h @@ -40,17 +40,17 @@ class nsWebPDecoder final : public Decod LexerResult ReadData(); LexerResult ReadHeader(WebPDemuxer* aDemuxer, bool aIsComplete); LexerResult ReadPayload(WebPDemuxer* aDemuxer, bool aIsComplete); nsresult CreateFrame(const nsIntRect& aFrameRect); void EndFrame(); LexerResult ReadSingle(const uint8_t* aData, size_t aLength, - const IntRect& aFrameRect); + const gfx::IntRect& aFrameRect); LexerResult ReadMultiple(WebPDemuxer* aDemuxer, bool aIsComplete); /// The SurfacePipe used to write to the output surface. SurfacePipe mPipe; /// The buffer used to accumulate data until the complete WebP header is /// received, if and only if the iterator is discontiguous. @@ -70,17 +70,17 @@ class nsWebPDecoder final : public Decod /// Frame timeout for the current frame; FrameTimeout mTimeout; /// Surface format for the current frame. gfx::SurfaceFormat mFormat; /// Frame rect for the current frame. - IntRect mFrameRect; + gfx::IntRect mFrameRect; /// The last row of decoded pixels written to mPipe. int mLastRow; /// Number of decoded frames. uint32_t mCurrentFrame; /// Pointer to the start of the contiguous encoded image data.
--- a/image/imgFrame.cpp +++ b/image/imgFrame.cpp @@ -7,31 +7,33 @@ #include "imgFrame.h" #include "ImageRegion.h" #include "ShutdownTracker.h" #include "SurfaceCache.h" #include "prenv.h" #include "gfx2DGlue.h" +#include "gfxContext.h" #include "gfxPlatform.h" #include "gfxUtils.h" #include "GeckoProfiler.h" #include "MainThreadUtils.h" #include "mozilla/CheckedInt.h" #include "mozilla/gfx/gfxVars.h" #include "mozilla/gfx/Tools.h" #include "mozilla/gfx/SourceSurfaceRawData.h" #include "mozilla/layers/SourceSurfaceSharedData.h" #include "mozilla/layers/SourceSurfaceVolatileData.h" #include "mozilla/Likely.h" #include "mozilla/MemoryReporting.h" #include "mozilla/StaticPrefs_browser.h" +#include "mozilla/StaticPrefs_image.h" #include "nsMargin.h" #include "nsRefreshDriver.h" #include "nsThreadUtils.h" #include <algorithm> // for min, max namespace mozilla {
--- a/image/imgRequestProxy.cpp +++ b/image/imgRequestProxy.cpp @@ -9,16 +9,17 @@ #include <utility> #include "Image.h" #include "ImageLogging.h" #include "ImageOps.h" #include "ImageTypes.h" #include "imgINotificationObserver.h" #include "imgLoader.h" +#include "mozilla/dom/Document.h" #include "mozilla/Telemetry.h" // for Telemetry #include "mozilla/dom/DocGroup.h" // for DocGroup #include "nsCRTGlue.h" #include "nsError.h" using namespace mozilla; using namespace mozilla::image; using mozilla::dom::Document;
--- a/image/imgTools.cpp +++ b/image/imgTools.cpp @@ -29,16 +29,17 @@ #include "Image.h" #include "IProgressObserver.h" #include "ScriptedNotificationObserver.h" #include "imgIScriptedNotificationObserver.h" #include "gfxPlatform.h" #include "js/ArrayBuffer.h" #include "js/RootingAPI.h" // JS::{Handle,Rooted} #include "js/Value.h" // JS::Value +#include "Orientation.h" using namespace mozilla::gfx; namespace mozilla { namespace image { namespace {
--- a/image/test/gtest/Common.h +++ b/image/test/gtest/Common.h @@ -532,12 +532,17 @@ ImageTestCase PerfRgbAlphaPNGTestCase(); ImageTestCase PerfGrayPNGTestCase(); ImageTestCase PerfGrayAlphaPNGTestCase(); ImageTestCase PerfRgbLosslessWebPTestCase(); ImageTestCase PerfRgbAlphaLosslessWebPTestCase(); ImageTestCase PerfRgbLossyWebPTestCase(); ImageTestCase PerfRgbAlphaLossyWebPTestCase(); ImageTestCase PerfRgbGIFTestCase(); +ImageTestCase CorruptAVIFTestCase(); +ImageTestCase DownscaledAVIFTestCase(); +ImageTestCase LargeAVIFTestCase(); +ImageTestCase MultiLayerAVIFTestCase(); +ImageTestCase TransparentAVIFTestCase(); } // namespace image } // namespace mozilla #endif // mozilla_image_test_gtest_Common_h
--- a/image/test/gtest/TestAnimationFrameBuffer.cpp +++ b/image/test/gtest/TestAnimationFrameBuffer.cpp @@ -1,30 +1,33 @@ /* -*- 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/. */ #include <utility> #include "AnimationFrameBuffer.h" +#include "Common.h" #include "gtest/gtest.h" using namespace mozilla; using namespace mozilla::image; static already_AddRefed<imgFrame> CreateEmptyFrame( - const IntSize& aSize = IntSize(1, 1), - const IntRect& aFrameRect = IntRect(0, 0, 1, 1), bool aCanRecycle = true) { + const gfx::IntSize& aSize = gfx::IntSize(1, 1), + const gfx::IntRect& aFrameRect = gfx::IntRect(0, 0, 1, 1), + bool aCanRecycle = true) { RefPtr<imgFrame> frame = new imgFrame(); AnimationParams animParams{aFrameRect, FrameTimeout::Forever(), /* aFrameNum */ 1, BlendMethod::OVER, DisposalMethod::NOT_SPECIFIED}; - nsresult rv = frame->InitForDecoder(aSize, SurfaceFormat::OS_RGBA, false, - Some(animParams), aCanRecycle); + nsresult rv = + frame->InitForDecoder(aSize, mozilla::gfx::SurfaceFormat::OS_RGBA, false, + Some(animParams), aCanRecycle); EXPECT_TRUE(NS_SUCCEEDED(rv)); RawAccessFrameRef frameRef = frame->RawAccessRef(); frame->SetRawAccessOnly(); // Normally the blend animation filter would set the dirty rect, but since // we aren't producing an actual animation here, we need to fake it. frame->SetDirtyRect(aFrameRect); frame->Finish(); return frame.forget(); @@ -126,20 +129,19 @@ static void VerifyInsertAndAdvance( VerifyInsertInternal(aQueue, frame); // Advance the display frame. bool expectedRestartDecoder = aExpectedStatus == AnimationFrameBuffer::InsertStatus::YIELD; VerifyAdvance(aQueue, aExpectedFrame, expectedRestartDecoder); } -static void VerifyMarkComplete(AnimationFrameBuffer& aQueue, - bool aExpectedContinue, - const IntRect& aRefreshArea = IntRect(0, 0, 1, - 1)) { +static void VerifyMarkComplete( + AnimationFrameBuffer& aQueue, bool aExpectedContinue, + const gfx::IntRect& aRefreshArea = gfx::IntRect(0, 0, 1, 1)) { if (aQueue.IsRecycling() && !aQueue.SizeKnown()) { const AnimationFrameRecyclingQueue& queue = *static_cast<AnimationFrameRecyclingQueue*>(&aQueue); EXPECT_EQ(queue.FirstFrame()->GetRect(), queue.FirstFrameRefreshArea()); } bool keepDecoding = aQueue.MarkComplete(aRefreshArea); EXPECT_EQ(aExpectedContinue, keepDecoding); @@ -253,17 +255,17 @@ TEST_F(ImageAnimationFrameBuffer, Finish RefPtr<imgFrame> frame = CreateEmptyFrame(); auto status = buffer.Insert(RefPtr<imgFrame>(frame)); EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::CONTINUE); EXPECT_FALSE(buffer.SizeKnown()); EXPECT_EQ(buffer.Size(), i + 1); if (i == 4) { EXPECT_EQ(size_t(15), buffer.PendingDecode()); - bool keepDecoding = buffer.MarkComplete(IntRect(0, 0, 1, 1)); + bool keepDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1)); EXPECT_FALSE(keepDecoding); EXPECT_TRUE(buffer.SizeKnown()); EXPECT_EQ(size_t(0), buffer.PendingDecode()); EXPECT_FALSE(buffer.HasRedecodeError()); } EXPECT_FALSE(buffer.MayDiscard()); @@ -327,17 +329,17 @@ TEST_F(ImageAnimationFrameBuffer, Finish } while (!restartDecoder); EXPECT_EQ(size_t(2), buffer.PendingDecode()); EXPECT_EQ(size_t(2), buffer.Displayed()); // Add the last frame. status = buffer.Insert(CreateEmptyFrame()); EXPECT_EQ(status, AnimationFrameBuffer::InsertStatus::CONTINUE); - bool keepDecoding = buffer.MarkComplete(IntRect(0, 0, 1, 1)); + bool keepDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1)); EXPECT_FALSE(keepDecoding); EXPECT_TRUE(buffer.SizeKnown()); EXPECT_EQ(size_t(0), buffer.PendingDecode()); EXPECT_EQ(size_t(5), frames.Length()); EXPECT_FALSE(buffer.HasRedecodeError()); // Finish progressing through the animation. for (; i < frames.Length(); ++i) { @@ -556,30 +558,30 @@ TEST_F(ImageAnimationFrameBuffer, Recycl // We should not start with any recycled frames. ASSERT_TRUE(buffer.Recycle().empty()); TestDiscardingQueueLoop(buffer, firstFrame, kThreshold, kBatch, kStartFrame); // All the frames we inserted should have been recycleable. ASSERT_FALSE(buffer.Recycle().empty()); while (!buffer.Recycle().empty()) { - IntRect expectedRect(0, 0, 1, 1); + gfx::IntRect expectedRect(0, 0, 1, 1); RefPtr<imgFrame> expectedFrame = buffer.Recycle().front().mFrame; EXPECT_FALSE(expectedRect.IsEmpty()); EXPECT_TRUE(expectedFrame.get() != nullptr); - IntRect gotRect; + gfx::IntRect gotRect; RawAccessFrameRef gotFrame = buffer.RecycleFrame(gotRect); EXPECT_EQ(expectedFrame.get(), gotFrame.get()); EXPECT_EQ(expectedRect, gotRect); EXPECT_TRUE(ReinitForRecycle(gotFrame)); } // Trying to pull a recycled frame when we have nothing should be safe too. - IntRect gotRect; + gfx::IntRect gotRect; RawAccessFrameRef gotFrame = buffer.RecycleFrame(gotRect); EXPECT_TRUE(gotFrame.get() == nullptr); EXPECT_FALSE(ReinitForRecycle(gotFrame)); } static void TestDiscardingQueueReset(AnimationFrameDiscardingQueue& aQueue, const imgFrame* aFirstFrame, size_t aThreshold, size_t aBatch, @@ -648,28 +650,28 @@ TEST_F(ImageAnimationFrameBuffer, Discar VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::DISCARD_YIELD); // Insert one more frame. AnimationFrameDiscardingQueue buffer(std::move(retained)); VerifyAdvance(buffer, 2, true); VerifyInsert(buffer, AnimationFrameBuffer::InsertStatus::YIELD); // Mark it as complete. - bool restartDecoder = buffer.MarkComplete(IntRect(0, 0, 1, 1)); + bool restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1)); EXPECT_FALSE(restartDecoder); EXPECT_FALSE(buffer.HasRedecodeError()); // Insert one fewer frame than before. VerifyAdvance(buffer, 3, true); VerifyInsertAndAdvance(buffer, 0, AnimationFrameBuffer::InsertStatus::YIELD); VerifyInsertAndAdvance(buffer, 1, AnimationFrameBuffer::InsertStatus::YIELD); VerifyInsertAndAdvance(buffer, 2, AnimationFrameBuffer::InsertStatus::YIELD); // When we mark it as complete, it should fail due to too few frames. - restartDecoder = buffer.MarkComplete(IntRect(0, 0, 1, 1)); + restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1)); EXPECT_TRUE(buffer.HasRedecodeError()); EXPECT_EQ(size_t(0), buffer.PendingDecode()); EXPECT_EQ(size_t(4), buffer.Size()); } TEST_F(ImageAnimationFrameBuffer, DiscardingTooManyFrames) { const size_t kThreshold = 3; const size_t kBatch = 1; @@ -683,17 +685,17 @@ TEST_F(ImageAnimationFrameBuffer, Discar VerifyInsert(retained, AnimationFrameBuffer::InsertStatus::DISCARD_YIELD); // Insert one more frame. AnimationFrameDiscardingQueue buffer(std::move(retained)); VerifyAdvance(buffer, 2, true); VerifyInsert(buffer, AnimationFrameBuffer::InsertStatus::YIELD); // Mark it as complete. - bool restartDecoder = buffer.MarkComplete(IntRect(0, 0, 1, 1)); + bool restartDecoder = buffer.MarkComplete(gfx::IntRect(0, 0, 1, 1)); EXPECT_FALSE(restartDecoder); EXPECT_FALSE(buffer.HasRedecodeError()); // Advance and insert to get us back to the end on the redecode. VerifyAdvance(buffer, 3, true); VerifyInsertAndAdvance(buffer, 0, AnimationFrameBuffer::InsertStatus::YIELD); VerifyInsertAndAdvance(buffer, 1, AnimationFrameBuffer::InsertStatus::YIELD); VerifyInsertAndAdvance(buffer, 2, AnimationFrameBuffer::InsertStatus::YIELD); @@ -718,60 +720,63 @@ TEST_F(ImageAnimationFrameBuffer, Recycl AnimationFrameRecyclingQueue buffer(std::move(retained)); TestDiscardingQueueReset(buffer, firstFrame, kThreshold, kBatch, kStartFrame); } TEST_F(ImageAnimationFrameBuffer, RecyclingResetBeforeComplete) { const size_t kThreshold = 3; const size_t kBatch = 1; const size_t kStartFrame = 0; - const IntSize kImageSize(100, 100); - const IntRect kImageRect(IntPoint(0, 0), kImageSize); + const gfx::IntSize kImageSize(100, 100); + const gfx::IntRect kImageRect(gfx::IntPoint(0, 0), kImageSize); AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame); // Get the starting buffer to just before the point where we need to switch // to a discarding buffer, reset the animation so advancing points at the // first frame, and insert the last frame to cross the threshold. RefPtr<imgFrame> frame; frame = CreateEmptyFrame(kImageSize, kImageRect, false); AnimationFrameBuffer::InsertStatus status = retained.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status); - frame = CreateEmptyFrame(kImageSize, IntRect(IntPoint(10, 10), IntSize(1, 1)), - false); + frame = CreateEmptyFrame( + kImageSize, gfx::IntRect(gfx::IntPoint(10, 10), gfx::IntSize(1, 1)), + false); status = retained.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); VerifyAdvance(retained, 1, true); - frame = CreateEmptyFrame(kImageSize, IntRect(IntPoint(20, 10), IntSize(1, 1)), - false); + frame = CreateEmptyFrame( + kImageSize, gfx::IntRect(gfx::IntPoint(20, 10), gfx::IntSize(1, 1)), + false); status = retained.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::DISCARD_YIELD, status); AnimationFrameRecyclingQueue buffer(std::move(retained)); bool restartDecoding = buffer.Reset(); EXPECT_TRUE(restartDecoding); // None of the buffers were recyclable. EXPECT_FALSE(buffer.Recycle().empty()); while (!buffer.Recycle().empty()) { - IntRect recycleRect; + gfx::IntRect recycleRect; RawAccessFrameRef frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_FALSE(ReinitForRecycle(frameRef)); } // Reinsert the first two frames as recyclable and reset again. frame = CreateEmptyFrame(kImageSize, kImageRect, true); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status); - frame = CreateEmptyFrame(kImageSize, IntRect(IntPoint(10, 10), IntSize(1, 1)), - true); + frame = CreateEmptyFrame( + kImageSize, gfx::IntRect(gfx::IntPoint(10, 10), gfx::IntSize(1, 1)), + true); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); restartDecoding = buffer.Reset(); EXPECT_TRUE(restartDecoding); // Now both buffers should have been saved and the dirty rect replaced with // the full image rect since we don't know the first frame refresh area yet. @@ -780,18 +785,18 @@ TEST_F(ImageAnimationFrameBuffer, Recycl EXPECT_EQ(kImageRect, entry.mDirtyRect); } } TEST_F(ImageAnimationFrameBuffer, RecyclingRect) { const size_t kThreshold = 5; const size_t kBatch = 2; const size_t kStartFrame = 0; - const IntSize kImageSize(100, 100); - const IntRect kImageRect(IntPoint(0, 0), kImageSize); + const gfx::IntSize kImageSize(100, 100); + const gfx::IntRect kImageRect(gfx::IntPoint(0, 0), kImageSize); AnimationFrameRetainedBuffer retained(kThreshold, kBatch, kStartFrame); // Let's get to the recycling state while marking all of the frames as not // recyclable, just like AnimationFrameBuffer / the decoders would do. RefPtr<imgFrame> frame; frame = CreateEmptyFrame(kImageSize, kImageRect, false); AnimationFrameBuffer::InsertStatus status = retained.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::CONTINUE, status); @@ -817,75 +822,75 @@ TEST_F(ImageAnimationFrameBuffer, Recycl EXPECT_EQ(AnimationFrameBuffer::InsertStatus::DISCARD_CONTINUE, status); AnimationFrameRecyclingQueue buffer(std::move(retained)); // The first frame is now the candidate for recycling. Since it was marked as // not recyclable, we should get nothing. VerifyAdvance(buffer, 4, false); - IntRect recycleRect; + gfx::IntRect recycleRect; EXPECT_FALSE(buffer.Recycle().empty()); RawAccessFrameRef frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_FALSE(ReinitForRecycle(frameRef)); EXPECT_TRUE(buffer.Recycle().empty()); // Insert a recyclable partial frame. Its dirty rect shouldn't matter since // the previous frame was not recyclable. - frame = CreateEmptyFrame(kImageSize, IntRect(0, 0, 25, 25)); + frame = CreateEmptyFrame(kImageSize, gfx::IntRect(0, 0, 25, 25)); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); VerifyAdvance(buffer, 5, true); EXPECT_FALSE(buffer.Recycle().empty()); frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_FALSE(ReinitForRecycle(frameRef)); EXPECT_TRUE(buffer.Recycle().empty()); // Insert a recyclable partial frame. Its dirty rect should match the recycle // rect since it is the only frame in the buffer. - frame = CreateEmptyFrame(kImageSize, IntRect(25, 0, 50, 50)); + frame = CreateEmptyFrame(kImageSize, gfx::IntRect(25, 0, 50, 50)); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); VerifyAdvance(buffer, 6, true); EXPECT_FALSE(buffer.Recycle().empty()); frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_TRUE(ReinitForRecycle(frameRef)); - EXPECT_EQ(IntRect(25, 0, 50, 50), recycleRect); + EXPECT_EQ(gfx::IntRect(25, 0, 50, 50), recycleRect); EXPECT_TRUE(buffer.Recycle().empty()); // Insert the last frame and mark us as complete. The next recycled frame is // producing the first frame again, so we should use the first frame refresh // area instead of its dirty rect. - frame = CreateEmptyFrame(kImageSize, IntRect(10, 10, 60, 10)); + frame = CreateEmptyFrame(kImageSize, gfx::IntRect(10, 10, 60, 10)); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); - bool continueDecoding = buffer.MarkComplete(IntRect(0, 0, 75, 50)); + bool continueDecoding = buffer.MarkComplete(gfx::IntRect(0, 0, 75, 50)); EXPECT_FALSE(continueDecoding); VerifyAdvance(buffer, 7, true); EXPECT_FALSE(buffer.Recycle().empty()); frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_TRUE(ReinitForRecycle(frameRef)); - EXPECT_EQ(IntRect(0, 0, 75, 50), recycleRect); + EXPECT_EQ(gfx::IntRect(0, 0, 75, 50), recycleRect); EXPECT_TRUE(buffer.Recycle().empty()); // Now let's reinsert the first frame. The recycle rect should still be the // first frame refresh area instead of the dirty rect of the first frame (e.g. // the full frame). frame = CreateEmptyFrame(kImageSize, kImageRect, false); status = buffer.Insert(std::move(frame)); EXPECT_EQ(AnimationFrameBuffer::InsertStatus::YIELD, status); VerifyAdvance(buffer, 0, true); EXPECT_FALSE(buffer.Recycle().empty()); frameRef = buffer.RecycleFrame(recycleRect); EXPECT_TRUE(frameRef); EXPECT_TRUE(ReinitForRecycle(frameRef)); - EXPECT_EQ(IntRect(0, 0, 75, 50), recycleRect); + EXPECT_EQ(gfx::IntRect(0, 0, 75, 50), recycleRect); EXPECT_TRUE(buffer.Recycle().empty()); }
--- a/image/test/gtest/TestFrameAnimator.cpp +++ b/image/test/gtest/TestFrameAnimator.cpp @@ -2,16 +2,18 @@ * 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/. */ #include "gtest/gtest.h" #include "Common.h" #include "AnimationSurfaceProvider.h" #include "Decoder.h" +#include "ImageFactory.h" +#include "nsIInputStream.h" #include "RasterImage.h" using namespace mozilla; using namespace mozilla::gfx; using namespace mozilla::image; static void CheckFrameAnimatorBlendResults(const ImageTestCase& aTestCase, RasterImage* aImage) {