diff --git a/image/ClippedImage.cpp b/image/ClippedImage.cpp index 2434c85984137..dc2a4e5a1be66 100644 --- a/image/ClippedImage.cpp +++ b/image/ClippedImage.cpp @@ -318,6 +318,27 @@ ClippedImage::GetImageContainerAtSize(WindowRenderer* aRenderer, return ImgDrawResult::NOT_SUPPORTED; } +NS_IMETHODIMP_(ImgDrawResult) +ClippedImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + // XXX(seth): We currently don't have a way of clipping the result of + // GetImageContainer. We work around this by always returning null, but if it + // ever turns out that ClippedImage is widely used on codepaths that can + // actually benefit from GetImageContainer, it would be a good idea to fix + // that method for performance reasons. + + if (!ShouldClip()) { + return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext, + aRegion, aFlags, aProvider); + } + + return ImgDrawResult::NOT_SUPPORTED; +} + static bool MustCreateSurface(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, const uint32_t aFlags) { diff --git a/image/ClippedImage.h b/image/ClippedImage.h index 1f0c9d635e61e..b0e3a0422cfdb 100644 --- a/image/ClippedImage.h +++ b/image/ClippedImage.h @@ -51,6 +51,11 @@ class ClippedImage : public ImageWrapper { const Maybe& aRegion, uint32_t aFlags, layers::ImageContainer** aOutContainer) override; NS_IMETHOD_(ImgDrawResult) + GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, uint32_t aFlags, + WebRenderImageProvider** aProvider) override; + NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter, const Maybe& aSVGContext, uint32_t aFlags, diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp index ee7e5e4f97840..69406d3d0c312 100644 --- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -177,6 +177,16 @@ DynamicImage::GetImageContainerAtSize(WindowRenderer* aRenderer, return ImgDrawResult::NOT_SUPPORTED; } +NS_IMETHODIMP_(ImgDrawResult) +DynamicImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + return ImgDrawResult::NOT_SUPPORTED; +} + NS_IMETHODIMP_(ImgDrawResult) DynamicImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, diff --git a/image/FrozenImage.cpp b/image/FrozenImage.cpp index d77fa7182241f..47a6622583591 100644 --- a/image/FrozenImage.cpp +++ b/image/FrozenImage.cpp @@ -79,6 +79,26 @@ FrozenImage::GetImageContainerAtSize(WindowRenderer* aRenderer, return ImgDrawResult::NOT_SUPPORTED; } +NS_IMETHODIMP_(ImgDrawResult) +FrozenImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + if (IsNonAnimated()) { + return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext, + aRegion, aFlags, aProvider); + } + + // XXX(seth): GetImageContainer does not currently support anything but the + // current frame. We work around this by always returning null, but if it ever + // turns out that FrozenImage is widely used on codepaths that can actually + // benefit from GetImageContainer, it would be a good idea to fix that method + // for performance reasons. + return ImgDrawResult::NOT_SUPPORTED; +} + NS_IMETHODIMP_(ImgDrawResult) FrozenImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, diff --git a/image/FrozenImage.h b/image/FrozenImage.h index 3dcf8fae14132..98b526ba9c92c 100644 --- a/image/FrozenImage.h +++ b/image/FrozenImage.h @@ -50,6 +50,11 @@ class FrozenImage : public ImageWrapper { const Maybe& aRegion, uint32_t aFlags, layers::ImageContainer** aOutContainer) override; NS_IMETHOD_(ImgDrawResult) + GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, uint32_t aFlags, + WebRenderImageProvider** aProvider) override; + NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter, const Maybe& aSVGContext, uint32_t aFlags, diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp index f5a24cf853e41..d1789dc595db2 100644 --- a/image/ImageWrapper.cpp +++ b/image/ImageWrapper.cpp @@ -178,6 +178,17 @@ ImageWrapper::GetImageContainerAtSize(WindowRenderer* aRenderer, aRegion, aFlags, aOutContainer); } +NS_IMETHODIMP_(ImgDrawResult) +ImageWrapper::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + return mInnerImage->GetImageProvider(aRenderer, aSize, aSVGContext, aRegion, + aFlags, aProvider); +} + NS_IMETHODIMP_(ImgDrawResult) ImageWrapper::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, diff --git a/image/OrientedImage.cpp b/image/OrientedImage.cpp index eaa43b335c3ee..7ddb515a6bca3 100644 --- a/image/OrientedImage.cpp +++ b/image/OrientedImage.cpp @@ -175,6 +175,27 @@ OrientedImage::GetImageContainerAtSize( return ImgDrawResult::NOT_SUPPORTED; } +NS_IMETHODIMP_(ImgDrawResult) +OrientedImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + // XXX(seth): We currently don't have a way of orienting the result of + // GetImageContainer. We work around this by always returning null, but if it + // ever turns out that OrientedImage is widely used on codepaths that can + // actually benefit from GetImageContainer, it would be a good idea to fix + // that method for performance reasons. + + if (mOrientation.IsIdentity()) { + return InnerImage()->GetImageProvider(aRenderer, aSize, aSVGContext, + aRegion, aFlags, aProvider); + } + + return ImgDrawResult::NOT_SUPPORTED; +} + struct MatrixBuilder { explicit MatrixBuilder(bool aInvert) : mInvert(aInvert) {} diff --git a/image/OrientedImage.h b/image/OrientedImage.h index 2fa704a94ab99..81fc4def02982 100644 --- a/image/OrientedImage.h +++ b/image/OrientedImage.h @@ -46,6 +46,11 @@ class OrientedImage : public ImageWrapper { const Maybe& aRegion, uint32_t aFlags, layers::ImageContainer** aOutContainer) override; NS_IMETHOD_(ImgDrawResult) + GetImageProvider(WindowRenderer* aRenderer, const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, uint32_t aFlags, + WebRenderImageProvider** aProvider) override; + NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, gfx::SamplingFilter aSamplingFilter, const Maybe& aSVGContext, uint32_t aFlags, diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 5c7551ce5d046..abbcc8b8868b0 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -653,6 +653,16 @@ RasterImage::GetImageContainerAtSize(WindowRenderer* aRenderer, aOutContainer); } +NS_IMETHODIMP_(ImgDrawResult) +RasterImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + return ImgDrawResult::NOT_SUPPORTED; +} + size_t RasterImage::SizeOfSourceWithComputedFallback( SizeOfState& aState) const { return mSourceBuffer->SizeOfIncludingThisWithComputedFallback( diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index 1c92e7cc736aa..79f7f4fe67ab0 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -850,6 +850,17 @@ VectorImage::GetImageContainerAtSize(WindowRenderer* aRenderer, return rv; } +//****************************************************************************** +NS_IMETHODIMP_(ImgDrawResult) +VectorImage::GetImageProvider(WindowRenderer* aRenderer, + const gfx::IntSize& aSize, + const Maybe& aSVGContext, + const Maybe& aRegion, + uint32_t aFlags, + WebRenderImageProvider** aProvider) { + return ImgDrawResult::NOT_SUPPORTED; +} + bool VectorImage::MaybeRestrictSVGContext( Maybe& aNewSVGContext, const Maybe& aSVGContext, uint32_t aFlags) { diff --git a/image/imgIContainer.idl b/image/imgIContainer.idl index 88eccdb5b247f..ba203fab99cc3 100644 --- a/image/imgIContainer.idl +++ b/image/imgIContainer.idl @@ -48,6 +48,7 @@ namespace image { class ImageRegion; class ImageIntRegion; +class WebRenderImageProvider; struct Orientation; struct Resolution; @@ -70,6 +71,7 @@ native nsSize(nsSize); [ptr] native nsIFrame(nsIFrame); native TempRefImageContainer(already_AddRefed); [ptr] native ImageContainer(mozilla::layers::ImageContainer); +[ptr] native WebRenderImageProvider(mozilla::image::WebRenderImageProvider); [ref] native ImageRegion(mozilla::image::ImageRegion); [ptr] native WindowRenderer(mozilla::WindowRenderer); native Orientation(mozilla::image::Orientation); @@ -352,6 +354,33 @@ interface imgIContainer : nsISupports in uint32_t aFlags, out ImageContainer aOutContainer); + /** + * Attempts to find a WebRenderImageProvider containing the current frame at + * the given size. Match the requested size is best effort; it's not + * guaranteed that the surface you get will be a perfect match. (Some reasons + * you may get a surface of a different size include: if you requested + * upscaling, or if downscale-during-decode is disabled.) + * + * @param aRenderer The WindowRenderer which will be used to render the + * ImageContainer. + * @param aSVGContext If specified, SVG-related rendering context, such as + * overridden attributes on the image document's root + * node, and the size of the viewport that the full image + * would occupy. Ignored for raster images. + * @param aFlags Decoding / drawing flags (in other words, FLAG_* flags). + * Currently only FLAG_SYNC_DECODE and FLAG_SYNC_DECODE_IF_FAST + * are supported. + * @param aProvider Return value for WebRenderImageProvider for the current + * frame. May be null depending on the draw result. + * @return The draw result for the current frame. + */ + [noscript, notxpcom] ImgDrawResult getImageProvider(in WindowRenderer aRenderer, + [const] in nsIntSize aSize, + [const] in MaybeSVGImageContext aSVGContext, + [const] in MaybeImageIntRegion aRegion, + in uint32_t aFlags, + out WebRenderImageProvider aProvider); + /** * Draw the requested frame of this image onto the context specified. *