Bug 1711061 - Part 12. Change the display list to use WebRenderImageProvider. r=tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D126605
This commit is contained in:
Andrew Osmond 2021-10-27 01:24:35 +00:00
parent 77d044e944
commit c6eb106f04
11 changed files with 174 additions and 177 deletions

View file

@ -17,6 +17,7 @@
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h" #include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/Types.h" #include "mozilla/gfx/Types.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/AnimationHelper.h" #include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/ClipManager.h" #include "mozilla/layers/ClipManager.h"
#include "mozilla/layers/ImageClient.h" #include "mozilla/layers/ImageClient.h"
@ -40,6 +41,7 @@ namespace mozilla {
namespace layers { namespace layers {
using namespace gfx; using namespace gfx;
using namespace image;
static int sIndent; static int sIndent;
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -2009,24 +2011,22 @@ bool WebRenderCommandBuilder::PushImage(
return true; return true;
} }
Maybe<wr::BlobImageKey> WebRenderCommandBuilder::CreateBlobImageKey( Maybe<wr::ImageKey> WebRenderCommandBuilder::CreateImageProviderKey(
nsDisplayItem* aItem, ImageContainer* aContainer, nsDisplayItem* aItem, image::WebRenderImageProvider* aProvider,
mozilla::wr::IpcResourceUpdateQueue& aResources) { mozilla::wr::IpcResourceUpdateQueue& aResources) {
MOZ_ASSERT(!aContainer->IsAsync()); RefPtr<WebRenderImageProviderData> imageData =
CreateOrRecycleWebRenderUserData<WebRenderImageProviderData>(aItem);
RefPtr<WebRenderBlobImageData> imageData =
CreateOrRecycleWebRenderUserData<WebRenderBlobImageData>(aItem);
MOZ_ASSERT(imageData); MOZ_ASSERT(imageData);
return imageData->UpdateImageKey(aContainer, aResources); return imageData->UpdateImageKey(aProvider, aResources);
} }
bool WebRenderCommandBuilder::PushBlobImage( bool WebRenderCommandBuilder::PushImageProvider(
nsDisplayItem* aItem, ImageContainer* aContainer, nsDisplayItem* aItem, image::WebRenderImageProvider* aProvider,
mozilla::wr::DisplayListBuilder& aBuilder, mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources, mozilla::wr::IpcResourceUpdateQueue& aResources,
const LayoutDeviceRect& aRect, const LayoutDeviceRect& aClip) { const LayoutDeviceRect& aRect, const LayoutDeviceRect& aClip) {
Maybe<wr::BlobImageKey> key = Maybe<wr::ImageKey> key =
CreateBlobImageKey(aItem, aContainer, aResources); CreateImageProviderKey(aItem, aProvider, aResources);
if (!key) { if (!key) {
return false; return false;
} }
@ -2034,8 +2034,7 @@ bool WebRenderCommandBuilder::PushBlobImage(
auto rendering = wr::ToImageRendering(aItem->Frame()->UsedImageRendering()); auto rendering = wr::ToImageRendering(aItem->Frame()->UsedImageRendering());
auto r = wr::ToLayoutRect(aRect); auto r = wr::ToLayoutRect(aRect);
auto c = wr::ToLayoutRect(aClip); auto c = wr::ToLayoutRect(aClip);
aBuilder.PushImage(r, c, !aItem->BackfaceIsHidden(), rendering, aBuilder.PushImage(r, c, !aItem->BackfaceIsHidden(), rendering, key.value());
wr::AsImageKey(key.value()));
return true; return true;
} }

View file

@ -21,6 +21,10 @@
namespace mozilla { namespace mozilla {
namespace image {
class WebRenderImageProvider;
}
namespace layers { namespace layers {
class ImageClient; class ImageClient;
@ -65,8 +69,8 @@ class WebRenderCommandBuilder final {
mozilla::wr::ImageRendering aRendering, const StackingContextHelper& aSc, mozilla::wr::ImageRendering aRendering, const StackingContextHelper& aSc,
gfx::IntSize& aSize, const Maybe<LayoutDeviceRect>& aAsyncImageBounds); gfx::IntSize& aSize, const Maybe<LayoutDeviceRect>& aAsyncImageBounds);
Maybe<wr::BlobImageKey> CreateBlobImageKey( Maybe<wr::ImageKey> CreateImageProviderKey(
nsDisplayItem* aItem, ImageContainer* aContainer, nsDisplayItem* aItem, image::WebRenderImageProvider* aProvider,
mozilla::wr::IpcResourceUpdateQueue& aResources); mozilla::wr::IpcResourceUpdateQueue& aResources);
WebRenderUserDataRefTable* GetWebRenderUserDataTable() { WebRenderUserDataRefTable* GetWebRenderUserDataTable() {
@ -79,11 +83,12 @@ class WebRenderCommandBuilder final {
const StackingContextHelper& aSc, const StackingContextHelper& aSc,
const LayoutDeviceRect& aRect, const LayoutDeviceRect& aClip); const LayoutDeviceRect& aRect, const LayoutDeviceRect& aClip);
bool PushBlobImage(nsDisplayItem* aItem, ImageContainer* aContainer, bool PushImageProvider(nsDisplayItem* aItem,
mozilla::wr::DisplayListBuilder& aBuilder, image::WebRenderImageProvider* aProvider,
mozilla::wr::IpcResourceUpdateQueue& aResources, mozilla::wr::DisplayListBuilder& aBuilder,
const LayoutDeviceRect& aRect, mozilla::wr::IpcResourceUpdateQueue& aResources,
const LayoutDeviceRect& aClip); const LayoutDeviceRect& aRect,
const LayoutDeviceRect& aClip);
Maybe<wr::ImageMask> BuildWrMaskImage( Maybe<wr::ImageMask> BuildWrMaskImage(
nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder, nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder,

View file

@ -6,6 +6,7 @@
#include "WebRenderUserData.h" #include "WebRenderUserData.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/AnimationHelper.h" #include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageClient.h" #include "mozilla/layers/ImageClient.h"
@ -19,6 +20,8 @@
#include "nsIFrame.h" #include "nsIFrame.h"
#include "WebRenderCanvasRenderer.h" #include "WebRenderCanvasRenderer.h"
using namespace mozilla::image;
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -42,8 +45,9 @@ bool WebRenderUserData::SupportsAsyncUpdate(nsIFrame* aFrame) {
} }
/* static */ /* static */
bool WebRenderUserData::ProcessInvalidateForImage( bool WebRenderUserData::ProcessInvalidateForImage(nsIFrame* aFrame,
nsIFrame* aFrame, DisplayItemType aType, ContainerProducerID aProducerId) { DisplayItemType aType,
ImageProviderId aProviderId) {
MOZ_ASSERT(aFrame); MOZ_ASSERT(aFrame);
if (!aFrame->HasProperty(WebRenderUserDataProperty::Key())) { if (!aFrame->HasProperty(WebRenderUserDataProperty::Key())) {
@ -59,9 +63,9 @@ bool WebRenderUserData::ProcessInvalidateForImage(
return true; return true;
} }
RefPtr<WebRenderImageData> image = RefPtr<WebRenderImageProviderData> image =
GetWebRenderUserData<WebRenderImageData>(aFrame, type); GetWebRenderUserData<WebRenderImageProviderData>(aFrame, type);
if (image && image->UsingSharedSurface(aProducerId)) { if (image && image->Invalidate(aProviderId)) {
return true; return true;
} }
@ -281,33 +285,43 @@ void WebRenderImageData::CreateImageClientIfNeeded() {
} }
} }
WebRenderBlobImageData::WebRenderBlobImageData(RenderRootStateManager* aManager, WebRenderImageProviderData::WebRenderImageProviderData(
nsDisplayItem* aItem) RenderRootStateManager* aManager, nsDisplayItem* aItem)
: WebRenderUserData(aManager, aItem) {} : WebRenderUserData(aManager, aItem) {}
WebRenderBlobImageData::WebRenderBlobImageData(RenderRootStateManager* aManager, WebRenderImageProviderData::WebRenderImageProviderData(
uint32_t aDisplayItemKey, RenderRootStateManager* aManager, uint32_t aDisplayItemKey,
nsIFrame* aFrame) nsIFrame* aFrame)
: WebRenderUserData(aManager, aDisplayItemKey, aFrame) {} : WebRenderUserData(aManager, aDisplayItemKey, aFrame) {}
Maybe<wr::BlobImageKey> WebRenderBlobImageData::UpdateImageKey( WebRenderImageProviderData::~WebRenderImageProviderData() = default;
ImageContainer* aContainer, wr::IpcResourceUpdateQueue& aResources) {
MOZ_ASSERT(aContainer);
if (mContainer != aContainer) { Maybe<wr::ImageKey> WebRenderImageProviderData::UpdateImageKey(
mContainer = aContainer; WebRenderImageProvider* aProvider, wr::IpcResourceUpdateQueue& aResources) {
MOZ_ASSERT(aProvider);
if (mProvider != aProvider) {
mProvider = aProvider;
} }
wr::BlobImageKey key = {}; wr::ImageKey key = {};
nsresult rv = mProvider->UpdateKey(mManager, aResources, key);
if (NS_FAILED(rv)) {
return Nothing();
}
return Some(key);
}
bool WebRenderImageProviderData::Invalidate(ImageProviderId aProviderId) const {
if (!aProviderId || mProvider->GetProviderId() != aProviderId) {
return false;
}
wr::ImageKey key = {};
nsresult rv = nsresult rv =
SharedSurfacesChild::ShareBlob(aContainer, mManager, aResources, key); mProvider->UpdateKey(mManager, mManager->AsyncResourceUpdates(), key);
if (NS_SUCCEEDED(rv)) { return NS_SUCCEEDED(rv);
mKey = Some(key);
} else {
mKey.reset();
}
return mKey;
} }
WebRenderFallbackData::WebRenderFallbackData(RenderRootStateManager* aManager, WebRenderFallbackData::WebRenderFallbackData(RenderRootStateManager* aManager,

View file

@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/AnimationInfo.h" #include "mozilla/layers/AnimationInfo.h"
#include "mozilla/dom/RemoteBrowser.h" #include "mozilla/dom/RemoteBrowser.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
@ -44,6 +45,7 @@ class WebRenderCanvasData;
class WebRenderCanvasRenderer; class WebRenderCanvasRenderer;
class WebRenderCanvasRendererAsync; class WebRenderCanvasRendererAsync;
class WebRenderImageData; class WebRenderImageData;
class WebRenderImageProviderData;
class WebRenderFallbackData; class WebRenderFallbackData;
class WebRenderLocalCanvasData; class WebRenderLocalCanvasData;
class RenderRootStateManager; class RenderRootStateManager;
@ -69,7 +71,7 @@ class WebRenderUserData {
static bool SupportsAsyncUpdate(nsIFrame* aFrame); static bool SupportsAsyncUpdate(nsIFrame* aFrame);
static bool ProcessInvalidateForImage(nsIFrame* aFrame, DisplayItemType aType, static bool ProcessInvalidateForImage(nsIFrame* aFrame, DisplayItemType aType,
ContainerProducerID aProducerId); image::ImageProviderId aProviderId);
NS_INLINE_DECL_REFCOUNTING(WebRenderUserData) NS_INLINE_DECL_REFCOUNTING(WebRenderUserData)
@ -78,6 +80,7 @@ class WebRenderUserData {
nsIFrame* aFrame); nsIFrame* aFrame);
virtual WebRenderImageData* AsImageData() { return nullptr; } virtual WebRenderImageData* AsImageData() { return nullptr; }
virtual WebRenderImageProviderData* AsImageProviderData() { return nullptr; }
virtual WebRenderFallbackData* AsFallbackData() { return nullptr; } virtual WebRenderFallbackData* AsFallbackData() { return nullptr; }
virtual WebRenderCanvasData* AsCanvasData() { return nullptr; } virtual WebRenderCanvasData* AsCanvasData() { return nullptr; }
virtual WebRenderLocalCanvasData* AsLocalCanvasData() { return nullptr; } virtual WebRenderLocalCanvasData* AsLocalCanvasData() { return nullptr; }
@ -93,7 +96,7 @@ class WebRenderUserData {
eRemote, eRemote,
eGroup, eGroup,
eMask, eMask,
eBlobImage, // SVG image eImageProvider, // ImageLib
}; };
virtual UserDataType GetType() = 0; virtual UserDataType GetType() = 0;
@ -186,26 +189,27 @@ class WebRenderImageData : public WebRenderUserData {
bool mOwnsKey; bool mOwnsKey;
}; };
/// Holds some data used to share blob recordings from VectorImages with the /// Holds some data used to share ImageLib results with the parent process.
/// parent process. /// This may be either in the form of a blob recording or a rasterized surface.
class WebRenderBlobImageData : public WebRenderUserData { class WebRenderImageProviderData final : public WebRenderUserData {
public: public:
WebRenderBlobImageData(RenderRootStateManager* aManager, WebRenderImageProviderData(RenderRootStateManager* aManager,
nsDisplayItem* aItem); nsDisplayItem* aItem);
WebRenderBlobImageData(RenderRootStateManager* aManager, WebRenderImageProviderData(RenderRootStateManager* aManager,
uint32_t aDisplayItemKey, nsIFrame* aFrame); uint32_t aDisplayItemKey, nsIFrame* aFrame);
virtual ~WebRenderBlobImageData() {} ~WebRenderImageProviderData() override;
UserDataType GetType() override { return UserDataType::eBlobImage; } WebRenderImageProviderData* AsImageProviderData() override { return this; }
static UserDataType Type() { return UserDataType::eBlobImage; } UserDataType GetType() override { return UserDataType::eImageProvider; }
Maybe<wr::BlobImageKey> GetImageKey() { return mKey; } static UserDataType Type() { return UserDataType::eImageProvider; }
Maybe<wr::BlobImageKey> UpdateImageKey( Maybe<wr::ImageKey> UpdateImageKey(image::WebRenderImageProvider* aProvider,
ImageContainer* aContainer, wr::IpcResourceUpdateQueue& aResources); wr::IpcResourceUpdateQueue& aResources);
bool Invalidate(image::ImageProviderId aProviderId) const;
protected: protected:
Maybe<wr::BlobImageKey> mKey; RefPtr<image::WebRenderImageProvider> mProvider;
RefPtr<ImageContainer> mContainer;
}; };
/// Used for fallback rendering. /// Used for fallback rendering.

View file

@ -6608,26 +6608,32 @@ IntSize nsLayoutUtils::ComputeImageContainerDrawingParameters(
imgIContainer::FRAME_CURRENT, samplingFilter, aFlags); imgIContainer::FRAME_CURRENT, samplingFilter, aFlags);
} }
// If the dest rect contains the fill rect, then we are only displaying part // We only use the region rect with blob recordings. This is because when we
// of the vector image. We need to calculate the restriction region to avoid // rasterize an SVG image in process, we always create a complete
// drawing more than we need, and sampling outside the desired bounds. // rasterization of the whole image which can be given to any caller, while
LayerIntRect clipRect = SnapRectForImage(itm, scaleFactors, aFillRect); // we support partial rasterization with the blob recordings.
if (destRect.Contains(clipRect)) { if (aFlags & imgIContainer::FLAG_RECORD_BLOB) {
LayerIntRect restrictRect = destRect.Intersect(clipRect); // If the dest rect contains the fill rect, then we are only displaying part
restrictRect.MoveBy(-destRect.TopLeft()); // of the vector image. We need to calculate the restriction region to avoid
// drawing more than we need, and sampling outside the desired bounds.
LayerIntRect clipRect = SnapRectForImage(itm, scaleFactors, aFillRect);
if (destRect.Contains(clipRect)) {
LayerIntRect restrictRect = destRect.Intersect(clipRect);
restrictRect.MoveBy(-destRect.TopLeft());
if (restrictRect.Width() < 1) { if (restrictRect.Width() < 1) {
restrictRect.SetWidth(1); restrictRect.SetWidth(1);
} }
if (restrictRect.Height() < 1) { if (restrictRect.Height() < 1) {
restrictRect.SetHeight(1); restrictRect.SetHeight(1);
} }
if (restrictRect.X() != 0 || restrictRect.Y() != 0 || if (restrictRect.X() != 0 || restrictRect.Y() != 0 ||
restrictRect.Size() != destRect.Size()) { restrictRect.Size() != destRect.Size()) {
IntRect sampleRect = restrictRect.ToUnknownRect(); IntRect sampleRect = restrictRect.ToUnknownRect();
aRegion = Some(ImageIntRegion::CreateWithSamplingRestriction( aRegion = Some(ImageIntRegion::CreateWithSamplingRestriction(
sampleRect, sampleRect, ExtendMode::CLAMP)); sampleRect, sampleRect, ExtendMode::CLAMP));
}
} }
} }

View file

@ -26,6 +26,7 @@
#include "mozilla/dom/HTMLAreaElement.h" #include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/dom/HTMLImageElement.h" #include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/ResponsiveImageSelector.h" #include "mozilla/dom/ResponsiveImageSelector.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/MouseEvents.h" #include "mozilla/MouseEvents.h"
@ -998,9 +999,8 @@ void nsImageFrame::InvalidateSelf(const nsIntRect* aLayerInvalidRect,
// Check if WebRender has interacted with this frame. If it has // Check if WebRender has interacted with this frame. If it has
// we need to let it know that things have changed. // we need to let it know that things have changed.
const auto type = DisplayItemType::TYPE_IMAGE; const auto type = DisplayItemType::TYPE_IMAGE;
const auto producerId = const auto providerId = mImage ? mImage->GetProviderId() : 0;
mImage ? mImage->GetProducerId() : kContainerProducerID_Invalid; if (WebRenderUserData::ProcessInvalidateForImage(this, type, providerId)) {
if (WebRenderUserData::ProcessInvalidateForImage(this, type, producerId)) {
return; return;
} }
@ -1843,13 +1843,13 @@ ImgDrawResult nsImageFrame::DisplayAltFeedbackWithoutLayer(
nsLayoutUtils::ComputeImageContainerDrawingParameters( nsLayoutUtils::ComputeImageContainerDrawingParameters(
imgCon, this, destRect, destRect, aSc, aFlags, svgContext, imgCon, this, destRect, destRect, aSc, aFlags, svgContext,
region); region);
RefPtr<ImageContainer> container; RefPtr<image::WebRenderImageProvider> provider;
result = imgCon->GetImageContainerAtSize( result = imgCon->GetImageProvider(aManager->LayerManager(), decodeSize,
aManager->LayerManager(), decodeSize, svgContext, region, aFlags, svgContext, region, aFlags,
getter_AddRefs(container)); getter_AddRefs(provider));
if (container) { if (provider) {
bool wrResult = aManager->CommandBuilder().PushImage( bool wrResult = aManager->CommandBuilder().PushImageProvider(
aItem, container, aBuilder, aResources, aSc, destRect, bounds); aItem, provider, aBuilder, aResources, destRect, bounds);
result &= wrResult ? ImgDrawResult::SUCCESS : ImgDrawResult::NOT_READY; result &= wrResult ? ImgDrawResult::SUCCESS : ImgDrawResult::NOT_READY;
} else { } else {
// We don't use &= here because we want the result to be NOT_READY so // We don't use &= here because we want the result to be NOT_READY so
@ -2098,10 +2098,10 @@ bool nsDisplayImage::CreateWebRenderCommands(
IntSize decodeSize = nsLayoutUtils::ComputeImageContainerDrawingParameters( IntSize decodeSize = nsLayoutUtils::ComputeImageContainerDrawingParameters(
mImage, mFrame, destRect, destRect, aSc, flags, svgContext, region); mImage, mFrame, destRect, destRect, aSc, flags, svgContext, region);
RefPtr<layers::ImageContainer> container; RefPtr<image::WebRenderImageProvider> provider;
ImgDrawResult drawResult = mImage->GetImageContainerAtSize( ImgDrawResult drawResult =
aManager->LayerManager(), decodeSize, svgContext, region, flags, mImage->GetImageProvider(aManager->LayerManager(), decodeSize, svgContext,
getter_AddRefs(container)); region, flags, getter_AddRefs(provider));
// While we got a container, it may not contain a fully decoded surface. If // While we got a container, it may not contain a fully decoded surface. If
// that is the case, and we have an image we were previously displaying which // that is the case, and we have an image we were previously displaying which
@ -2123,13 +2123,13 @@ bool nsDisplayImage::CreateWebRenderCommands(
prevFlags &= ~imgIContainer::FLAG_RECORD_BLOB; prevFlags &= ~imgIContainer::FLAG_RECORD_BLOB;
} }
RefPtr<ImageContainer> prevContainer; RefPtr<image::WebRenderImageProvider> prevProvider;
ImgDrawResult newDrawResult = mPrevImage->GetImageContainerAtSize( ImgDrawResult newDrawResult = mPrevImage->GetImageProvider(
aManager->LayerManager(), decodeSize, svgContext, region, prevFlags, aManager->LayerManager(), decodeSize, svgContext, region, prevFlags,
getter_AddRefs(prevContainer)); getter_AddRefs(prevProvider));
if (prevContainer && newDrawResult == ImgDrawResult::SUCCESS) { if (prevProvider && newDrawResult == ImgDrawResult::SUCCESS) {
drawResult = newDrawResult; drawResult = newDrawResult;
container = std::move(prevContainer); provider = std::move(prevProvider);
flags = prevFlags; flags = prevFlags;
break; break;
} }
@ -2156,14 +2156,9 @@ bool nsDisplayImage::CreateWebRenderCommands(
// If the image container is empty, we don't want to fallback. Any other // If the image container is empty, we don't want to fallback. Any other
// failure will be due to resource constraints and fallback is unlikely to // failure will be due to resource constraints and fallback is unlikely to
// help us. Hence we can ignore the return value from PushImage. // help us. Hence we can ignore the return value from PushImage.
if (container) { if (provider) {
if (flags & imgIContainer::FLAG_RECORD_BLOB) { aManager->CommandBuilder().PushImageProvider(
aManager->CommandBuilder().PushBlobImage(this, container, aBuilder, this, provider, aBuilder, aResources, destRect, destRect);
aResources, destRect, destRect);
} else {
aManager->CommandBuilder().PushImage(this, container, aBuilder,
aResources, aSc, destRect, destRect);
}
} }
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult);

View file

@ -29,6 +29,7 @@
#include "nsStyleStruct.h" #include "nsStyleStruct.h"
#include "gfx2DGlue.h" #include "gfx2DGlue.h"
#include "gfxGradientCache.h" #include "gfxGradientCache.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
@ -3628,20 +3629,17 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
img, aForFrame, imageRect, imageRect, aSc, flags, svgContext, img, aForFrame, imageRect, imageRect, aSc, flags, svgContext,
region); region);
RefPtr<layers::ImageContainer> container; RefPtr<WebRenderImageProvider> provider;
drawResult = img->GetImageContainerAtSize( drawResult = img->GetImageProvider(aManager->LayerManager(), decodeSize,
aManager->LayerManager(), decodeSize, svgContext, region, flags, svgContext, region, flags,
getter_AddRefs(container)); getter_AddRefs(provider));
if (!container) { if (!provider) {
break; break;
} }
auto rendering = Maybe<wr::ImageKey> key =
wr::ToImageRendering(aItem->Frame()->UsedImageRendering()); aManager->CommandBuilder().CreateImageProviderKey(aItem, provider,
gfx::IntSize size; aResources);
Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(
aItem, container, aBuilder, aResources, rendering, aSc, size,
Nothing());
if (key.isNothing()) { if (key.isNothing()) {
break; break;
} }
@ -3656,6 +3654,8 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands(
// but there are reftests that are sensible to the test going through a // but there are reftests that are sensible to the test going through a
// blob while the reference doesn't. // blob while the reference doesn't.
if (noVerticalBorders && noHorizontalBorders) { if (noVerticalBorders && noHorizontalBorders) {
auto rendering =
wr::ToImageRendering(aItem->Frame()->UsedImageRendering());
aBuilder.PushImage(dest, clip, !aItem->BackfaceIsHidden(), rendering, aBuilder.PushImage(dest, clip, !aItem->BackfaceIsHidden(), rendering,
key.value()); key.value());
break; break;

View file

@ -14,6 +14,7 @@
#include "gfxDrawable.h" #include "gfxDrawable.h"
#include "ImageOps.h" #include "ImageOps.h"
#include "ImageRegion.h" #include "ImageRegion.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/StackingContextHelper.h" #include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
@ -621,40 +622,30 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
mImageContainer, mForFrame, destRect, clipRect, aSc, mImageContainer, mForFrame, destRect, clipRect, aSc,
containerFlags, svgContext, region); containerFlags, svgContext, region);
if (extendMode != ExtendMode::CLAMP) { RefPtr<image::WebRenderImageProvider> provider;
region = Nothing(); drawResult = mImageContainer->GetImageProvider(
}
RefPtr<layers::ImageContainer> container;
drawResult = mImageContainer->GetImageContainerAtSize(
aManager->LayerManager(), decodeSize, svgContext, region, aManager->LayerManager(), decodeSize, svgContext, region,
containerFlags, getter_AddRefs(container)); containerFlags, getter_AddRefs(provider));
if (!container) { if (!provider) {
NS_WARNING("Failed to get image container"); NS_WARNING("Failed to get image container");
break; break;
} }
if (containerFlags & imgIContainer::FLAG_RECORD_BLOB) { Maybe<wr::ImageKey> key =
MOZ_ASSERT(extendMode == ExtendMode::CLAMP); aManager->CommandBuilder().CreateImageProviderKey(aItem, provider,
aManager->CommandBuilder().PushBlobImage( aResources);
aItem, container, aBuilder, aResources, clipRect, clipRect); if (key.isNothing()) {
break; break;
} }
auto rendering = auto rendering =
wr::ToImageRendering(aItem->Frame()->UsedImageRendering()); wr::ToImageRendering(aItem->Frame()->UsedImageRendering());
gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(
aItem, container, aBuilder, aResources, rendering, aSc, size,
Nothing());
if (key.isNothing()) {
break;
}
wr::LayoutRect dest = wr::ToLayoutRect(destRect);
wr::LayoutRect clip = wr::ToLayoutRect(clipRect); wr::LayoutRect clip = wr::ToLayoutRect(clipRect);
// If we provided a region to the provider, then it already took the
// dest rect into account when it did the recording.
wr::LayoutRect dest = region ? clip : wr::ToLayoutRect(destRect);
if (extendMode == ExtendMode::CLAMP) { if (extendMode == ExtendMode::CLAMP) {
// The image is not repeating. Just push as a regular image. // The image is not repeating. Just push as a regular image.
aBuilder.PushImage(dest, clip, !aItem->BackfaceIsHidden(), rendering, aBuilder.PushImage(dest, clip, !aItem->BackfaceIsHidden(), rendering,

View file

@ -540,9 +540,9 @@ static void InvalidateImages(nsIFrame* aFrame, imgIRequest* aRequest,
static_cast<layers::WebRenderMaskData*>(data.get())->Invalidate(); static_cast<layers::WebRenderMaskData*>(data.get())->Invalidate();
invalidateFrame = true; invalidateFrame = true;
break; break;
case layers::WebRenderUserData::UserDataType::eImage: case layers::WebRenderUserData::UserDataType::eImageProvider:
if (static_cast<layers::WebRenderImageData*>(data.get()) if (static_cast<layers::WebRenderImageProviderData*>(data.get())
->UsingSharedSurface(aRequest->GetProducerId())) { ->Invalidate(aRequest->GetProviderId())) {
break; break;
} }
[[fallthrough]]; [[fallthrough]];

View file

@ -10,6 +10,7 @@
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxPlatform.h" #include "gfxPlatform.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "imgIContainer.h" #include "imgIContainer.h"
@ -620,10 +621,10 @@ bool SVGImageFrame::CreateWebRenderCommands(
mImageContainer, this, destRect, clipRect, aSc, flags, svgContext, mImageContainer, this, destRect, clipRect, aSc, flags, svgContext,
region); region);
RefPtr<layers::ImageContainer> container; RefPtr<image::WebRenderImageProvider> provider;
ImgDrawResult drawResult = mImageContainer->GetImageContainerAtSize( ImgDrawResult drawResult = mImageContainer->GetImageProvider(
aManager->LayerManager(), decodeSize, svgContext, region, flags, aManager->LayerManager(), decodeSize, svgContext, region, flags,
getter_AddRefs(container)); getter_AddRefs(provider));
// While we got a container, it may not contain a fully decoded surface. If // While we got a container, it may not contain a fully decoded surface. If
// that is the case, and we have an image we were previously displaying which // that is the case, and we have an image we were previously displaying which
@ -647,14 +648,9 @@ bool SVGImageFrame::CreateWebRenderCommands(
// If the image container is empty, we don't want to fallback. Any other // If the image container is empty, we don't want to fallback. Any other
// failure will be due to resource constraints and fallback is unlikely to // failure will be due to resource constraints and fallback is unlikely to
// help us. Hence we can ignore the return value from PushImage. // help us. Hence we can ignore the return value from PushImage.
if (container) { if (provider) {
if (flags & imgIContainer::FLAG_RECORD_BLOB) { aManager->CommandBuilder().PushImageProvider(
aManager->CommandBuilder().PushBlobImage( aItem, provider, aBuilder, aResources, destRect, clipRect);
aItem, container, aBuilder, aResources, destRect, clipRect);
} else {
aManager->CommandBuilder().PushImage(
aItem, container, aBuilder, aResources, aSc, destRect, clipRect);
}
} }
nsDisplayItemGenericImageGeometry::UpdateDrawResult(aItem, drawResult); nsDisplayItemGenericImageGeometry::UpdateDrawResult(aItem, drawResult);

View file

@ -51,6 +51,7 @@
#include "mozilla/StaticPrefs_image.h" #include "mozilla/StaticPrefs_image.h"
#include "mozilla/SVGImageContext.h" #include "mozilla/SVGImageContext.h"
#include "Units.h" #include "Units.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/dom/ImageTracker.h" #include "mozilla/dom/ImageTracker.h"
@ -428,39 +429,25 @@ ImgDrawResult nsImageBoxFrame::CreateWebRenderCommands(
imgCon, aItem->Frame(), fillRect, fillRect, aSc, aFlags, svgContext, imgCon, aItem->Frame(), fillRect, fillRect, aSc, aFlags, svgContext,
region); region);
RefPtr<layers::ImageContainer> container; RefPtr<image::WebRenderImageProvider> provider;
result = imgCon->GetImageContainerAtSize(aManager->LayerManager(), decodeSize, result =
svgContext, region, aFlags, imgCon->GetImageProvider(aManager->LayerManager(), decodeSize, svgContext,
getter_AddRefs(container)); region, aFlags, getter_AddRefs(provider));
if (!container) { if (!provider) {
NS_WARNING("Failed to get image container"); NS_WARNING("Failed to get image provider");
return result; return result;
} }
auto rendering = wr::ToImageRendering(aItem->Frame()->UsedImageRendering()); auto rendering = wr::ToImageRendering(aItem->Frame()->UsedImageRendering());
wr::LayoutRect fill = wr::ToLayoutRect(fillRect); wr::LayoutRect fill = wr::ToLayoutRect(fillRect);
if (aFlags & imgIContainer::FLAG_RECORD_BLOB) { Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageProviderKey(
Maybe<wr::BlobImageKey> key = aManager->CommandBuilder().CreateBlobImageKey( aItem, provider, aResources);
aItem, container, aResources);
if (key.isNothing()) {
return result;
}
aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering,
wr::AsImageKey(key.value()));
return result;
}
gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(
aItem, container, aBuilder, aResources, rendering, aSc, size, Nothing());
if (key.isNothing()) { if (key.isNothing()) {
return result; return result;
} }
aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering, key.value()); aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering, key.value());
return result; return result;
} }
@ -841,8 +828,8 @@ void nsImageBoxFrame::OnFrameUpdate(imgIRequest* aRequest) {
// Check if WebRender has interacted with this frame. If it has // Check if WebRender has interacted with this frame. If it has
// we need to let it know that things have changed. // we need to let it know that things have changed.
const auto type = DisplayItemType::TYPE_XUL_IMAGE; const auto type = DisplayItemType::TYPE_XUL_IMAGE;
const auto producerId = aRequest->GetProducerId(); const auto providerId = aRequest->GetProviderId();
if (WebRenderUserData::ProcessInvalidateForImage(this, type, producerId)) { if (WebRenderUserData::ProcessInvalidateForImage(this, type, providerId)) {
return; return;
} }