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-26 13:28:27 +00:00
Родитель 7d6439b84a
Коммит 0ac282d26a
11 изменённых файлов: 174 добавлений и 177 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -6608,26 +6608,32 @@ IntSize nsLayoutUtils::ComputeImageContainerDrawingParameters(
imgIContainer::FRAME_CURRENT, samplingFilter, aFlags);
}
// If the dest rect contains the fill rect, then we are only displaying part
// 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());
// We only use the region rect with blob recordings. This is because when we
// rasterize an SVG image in process, we always create a complete
// rasterization of the whole image which can be given to any caller, while
// we support partial rasterization with the blob recordings.
if (aFlags & imgIContainer::FLAG_RECORD_BLOB) {
// If the dest rect contains the fill rect, then we are only displaying part
// 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) {
restrictRect.SetWidth(1);
}
if (restrictRect.Height() < 1) {
restrictRect.SetHeight(1);
}
if (restrictRect.Width() < 1) {
restrictRect.SetWidth(1);
}
if (restrictRect.Height() < 1) {
restrictRect.SetHeight(1);
}
if (restrictRect.X() != 0 || restrictRect.Y() != 0 ||
restrictRect.Size() != destRect.Size()) {
IntRect sampleRect = restrictRect.ToUnknownRect();
aRegion = Some(ImageIntRegion::CreateWithSamplingRestriction(
sampleRect, sampleRect, ExtendMode::CLAMP));
if (restrictRect.X() != 0 || restrictRect.Y() != 0 ||
restrictRect.Size() != destRect.Size()) {
IntRect sampleRect = restrictRect.ToUnknownRect();
aRegion = Some(ImageIntRegion::CreateWithSamplingRestriction(
sampleRect, sampleRect, ExtendMode::CLAMP));
}
}
}

Просмотреть файл

@ -26,6 +26,7 @@
#include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/ResponsiveImageSelector.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.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
// we need to let it know that things have changed.
const auto type = DisplayItemType::TYPE_IMAGE;
const auto producerId =
mImage ? mImage->GetProducerId() : kContainerProducerID_Invalid;
if (WebRenderUserData::ProcessInvalidateForImage(this, type, producerId)) {
const auto providerId = mImage ? mImage->GetProviderId() : 0;
if (WebRenderUserData::ProcessInvalidateForImage(this, type, providerId)) {
return;
}
@ -1843,13 +1843,13 @@ ImgDrawResult nsImageFrame::DisplayAltFeedbackWithoutLayer(
nsLayoutUtils::ComputeImageContainerDrawingParameters(
imgCon, this, destRect, destRect, aSc, aFlags, svgContext,
region);
RefPtr<ImageContainer> container;
result = imgCon->GetImageContainerAtSize(
aManager->LayerManager(), decodeSize, svgContext, region, aFlags,
getter_AddRefs(container));
if (container) {
bool wrResult = aManager->CommandBuilder().PushImage(
aItem, container, aBuilder, aResources, aSc, destRect, bounds);
RefPtr<image::WebRenderImageProvider> provider;
result = imgCon->GetImageProvider(aManager->LayerManager(), decodeSize,
svgContext, region, aFlags,
getter_AddRefs(provider));
if (provider) {
bool wrResult = aManager->CommandBuilder().PushImageProvider(
aItem, provider, aBuilder, aResources, destRect, bounds);
result &= wrResult ? ImgDrawResult::SUCCESS : ImgDrawResult::NOT_READY;
} else {
// 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(
mImage, mFrame, destRect, destRect, aSc, flags, svgContext, region);
RefPtr<layers::ImageContainer> container;
ImgDrawResult drawResult = mImage->GetImageContainerAtSize(
aManager->LayerManager(), decodeSize, svgContext, region, flags,
getter_AddRefs(container));
RefPtr<image::WebRenderImageProvider> provider;
ImgDrawResult drawResult =
mImage->GetImageProvider(aManager->LayerManager(), decodeSize, svgContext,
region, flags, getter_AddRefs(provider));
// 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
@ -2123,13 +2123,13 @@ bool nsDisplayImage::CreateWebRenderCommands(
prevFlags &= ~imgIContainer::FLAG_RECORD_BLOB;
}
RefPtr<ImageContainer> prevContainer;
ImgDrawResult newDrawResult = mPrevImage->GetImageContainerAtSize(
RefPtr<image::WebRenderImageProvider> prevProvider;
ImgDrawResult newDrawResult = mPrevImage->GetImageProvider(
aManager->LayerManager(), decodeSize, svgContext, region, prevFlags,
getter_AddRefs(prevContainer));
if (prevContainer && newDrawResult == ImgDrawResult::SUCCESS) {
getter_AddRefs(prevProvider));
if (prevProvider && newDrawResult == ImgDrawResult::SUCCESS) {
drawResult = newDrawResult;
container = std::move(prevContainer);
provider = std::move(prevProvider);
flags = prevFlags;
break;
}
@ -2156,14 +2156,9 @@ bool nsDisplayImage::CreateWebRenderCommands(
// 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
// help us. Hence we can ignore the return value from PushImage.
if (container) {
if (flags & imgIContainer::FLAG_RECORD_BLOB) {
aManager->CommandBuilder().PushBlobImage(this, container, aBuilder,
aResources, destRect, destRect);
} else {
aManager->CommandBuilder().PushImage(this, container, aBuilder,
aResources, aSc, destRect, destRect);
}
if (provider) {
aManager->CommandBuilder().PushImageProvider(
this, provider, aBuilder, aResources, destRect, destRect);
}
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult);

Просмотреть файл

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

Просмотреть файл

@ -14,6 +14,7 @@
#include "gfxDrawable.h"
#include "ImageOps.h"
#include "ImageRegion.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayerManager.h"
@ -621,40 +622,30 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
mImageContainer, mForFrame, destRect, clipRect, aSc,
containerFlags, svgContext, region);
if (extendMode != ExtendMode::CLAMP) {
region = Nothing();
}
RefPtr<layers::ImageContainer> container;
drawResult = mImageContainer->GetImageContainerAtSize(
RefPtr<image::WebRenderImageProvider> provider;
drawResult = mImageContainer->GetImageProvider(
aManager->LayerManager(), decodeSize, svgContext, region,
containerFlags, getter_AddRefs(container));
if (!container) {
containerFlags, getter_AddRefs(provider));
if (!provider) {
NS_WARNING("Failed to get image container");
break;
}
if (containerFlags & imgIContainer::FLAG_RECORD_BLOB) {
MOZ_ASSERT(extendMode == ExtendMode::CLAMP);
aManager->CommandBuilder().PushBlobImage(
aItem, container, aBuilder, aResources, clipRect, clipRect);
Maybe<wr::ImageKey> key =
aManager->CommandBuilder().CreateImageProviderKey(aItem, provider,
aResources);
if (key.isNothing()) {
break;
}
auto rendering =
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);
// 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) {
// The image is not repeating. Just push as a regular image.
aBuilder.PushImage(dest, clip, !aItem->BackfaceIsHidden(), rendering,

Просмотреть файл

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

Просмотреть файл

@ -10,6 +10,7 @@
#include "gfxContext.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/image/WebRenderImageProvider.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "imgIContainer.h"
@ -620,10 +621,10 @@ bool SVGImageFrame::CreateWebRenderCommands(
mImageContainer, this, destRect, clipRect, aSc, flags, svgContext,
region);
RefPtr<layers::ImageContainer> container;
ImgDrawResult drawResult = mImageContainer->GetImageContainerAtSize(
RefPtr<image::WebRenderImageProvider> provider;
ImgDrawResult drawResult = mImageContainer->GetImageProvider(
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
// 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
// failure will be due to resource constraints and fallback is unlikely to
// help us. Hence we can ignore the return value from PushImage.
if (container) {
if (flags & imgIContainer::FLAG_RECORD_BLOB) {
aManager->CommandBuilder().PushBlobImage(
aItem, container, aBuilder, aResources, destRect, clipRect);
} else {
aManager->CommandBuilder().PushImage(
aItem, container, aBuilder, aResources, aSc, destRect, clipRect);
}
if (provider) {
aManager->CommandBuilder().PushImageProvider(
aItem, provider, aBuilder, aResources, destRect, clipRect);
}
nsDisplayItemGenericImageGeometry::UpdateDrawResult(aItem, drawResult);

Просмотреть файл

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