Bug 1704792 - Part 3. Make display list items request blobs for SVG images. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D111838
This commit is contained in:
Andrew Osmond 2021-05-13 16:24:07 +00:00
Родитель 091cb4dc71
Коммит c82b7d67c2
5 изменённых файлов: 76 добавлений и 6 удалений

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

@ -30,6 +30,7 @@
#include "mozilla/MouseEvents.h" #include "mozilla/MouseEvents.h"
#include "mozilla/PresShell.h" #include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h" #include "mozilla/PresShellInlines.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/StaticPrefs_layout.h" #include "mozilla/StaticPrefs_layout.h"
#include "mozilla/SVGImageContext.h" #include "mozilla/SVGImageContext.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
@ -1998,6 +1999,10 @@ bool nsDisplayImage::CreateWebRenderCommands(
if (aDisplayListBuilder->UseHighQualityScaling()) { if (aDisplayListBuilder->UseHighQualityScaling()) {
flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
} }
if (StaticPrefs::image_svg_blob_image() &&
mImage->GetType() == imgIContainer::TYPE_VECTOR) {
flags |= imgIContainer::FLAG_RECORD_BLOB;
}
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel(); const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect( LayoutDeviceRect destRect(
@ -2021,13 +2026,25 @@ bool nsDisplayImage::CreateWebRenderCommands(
case ImgDrawResult::INCOMPLETE: case ImgDrawResult::INCOMPLETE:
case ImgDrawResult::TEMPORARY_ERROR: case ImgDrawResult::TEMPORARY_ERROR:
if (mPrevImage && mPrevImage != mImage) { if (mPrevImage && mPrevImage != mImage) {
// The current image and the previous image might be switching between
// rasterized surfaces and blob recordings, so we need to update the
// flags appropriately.
uint32_t prevFlags = flags;
if (StaticPrefs::image_svg_blob_image() &&
mPrevImage->GetType() == imgIContainer::TYPE_VECTOR) {
prevFlags |= imgIContainer::FLAG_RECORD_BLOB;
} else {
prevFlags &= ~imgIContainer::FLAG_RECORD_BLOB;
}
RefPtr<ImageContainer> prevContainer; RefPtr<ImageContainer> prevContainer;
ImgDrawResult newDrawResult = mPrevImage->GetImageContainerAtSize( ImgDrawResult newDrawResult = mPrevImage->GetImageContainerAtSize(
aManager->LayerManager(), decodeSize, svgContext, flags, aManager->LayerManager(), decodeSize, svgContext, prevFlags,
getter_AddRefs(prevContainer)); getter_AddRefs(prevContainer));
if (prevContainer && newDrawResult == ImgDrawResult::SUCCESS) { if (prevContainer && newDrawResult == ImgDrawResult::SUCCESS) {
drawResult = newDrawResult; drawResult = newDrawResult;
container = std::move(prevContainer); container = std::move(prevContainer);
flags = prevFlags;
break; break;
} }
@ -2054,8 +2071,13 @@ bool nsDisplayImage::CreateWebRenderCommands(
// 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 (container) {
aManager->CommandBuilder().PushImage(this, container, aBuilder, aResources, if (flags & imgIContainer::FLAG_RECORD_BLOB) {
aSc, destRect, destRect); aManager->CommandBuilder().PushBlobImage(this, container, aBuilder,
aResources, destRect, destRect);
} else {
aManager->CommandBuilder().PushImage(this, container, aBuilder,
aResources, aSc, destRect, destRect);
}
} }
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult);

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

@ -24,6 +24,7 @@
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsStyleStructInlines.h" #include "nsStyleStructInlines.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/ISVGDisplayableFrame.h" #include "mozilla/ISVGDisplayableFrame.h"
#include "mozilla/SVGIntegrationUtils.h" #include "mozilla/SVGIntegrationUtils.h"
#include "mozilla/SVGPaintServerFrame.h" #include "mozilla/SVGPaintServerFrame.h"
@ -588,6 +589,11 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
if (mFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) { if (mFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
containerFlags |= imgIContainer::FLAG_SYNC_DECODE; containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
} }
if (mExtendMode == ExtendMode::CLAMP &&
StaticPrefs::image_svg_blob_image() &&
mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
containerFlags |= imgIContainer::FLAG_RECORD_BLOB;
}
CSSIntSize destCSSSize{ CSSIntSize destCSSSize{
nsPresContext::AppUnitsToIntCSSPixels(aDest.width), nsPresContext::AppUnitsToIntCSSPixels(aDest.width),
@ -616,6 +622,15 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
break; break;
} }
if (containerFlags & imgIContainer::FLAG_RECORD_BLOB) {
MOZ_ASSERT(mExtendMode == ExtendMode::CLAMP);
LayoutDeviceRect clipRect =
LayoutDeviceRect::FromAppUnits(aFill, appUnitsPerDevPixel);
aManager->CommandBuilder().PushBlobImage(
aItem, container, aBuilder, aResources, destRect, clipRect);
break;
}
mozilla::wr::ImageRendering rendering = wr::ToImageRendering( mozilla::wr::ImageRendering rendering = wr::ToImageRendering(
nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame())); nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame()));
gfx::IntSize size; gfx::IntSize size;

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

@ -20,6 +20,7 @@
#include "SVGGeometryProperty.h" #include "SVGGeometryProperty.h"
#include "SVGGeometryFrame.h" #include "SVGGeometryFrame.h"
#include "mozilla/PresShell.h" #include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/SVGContentUtils.h" #include "mozilla/SVGContentUtils.h"
#include "mozilla/SVGImageContext.h" #include "mozilla/SVGImageContext.h"
#include "mozilla/SVGObserverUtils.h" #include "mozilla/SVGObserverUtils.h"
@ -602,6 +603,9 @@ bool SVGImageFrame::CreateWebRenderCommands(
Maybe<SVGImageContext> svgContext; Maybe<SVGImageContext> svgContext;
if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) { if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
if (StaticPrefs::image_svg_blob_image()) {
flags |= imgIContainer::FLAG_RECORD_BLOB;
}
// Forward preserveAspectRatio to inner SVGs // Forward preserveAspectRatio to inner SVGs
svgContext.emplace(Some(CSSIntSize::Truncate(width, height)), svgContext.emplace(Some(CSSIntSize::Truncate(width, height)),
Some(imgElem->mPreserveAspectRatio.GetAnimValue())); Some(imgElem->mPreserveAspectRatio.GetAnimValue()));
@ -639,8 +643,13 @@ bool SVGImageFrame::CreateWebRenderCommands(
// 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 (container) {
aManager->CommandBuilder().PushImage(aItem, container, aBuilder, if (flags & imgIContainer::FLAG_RECORD_BLOB) {
aResources, aSc, destRect, clipRect); aManager->CommandBuilder().PushBlobImage(
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);

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

@ -48,6 +48,7 @@
#include "mozilla/EventDispatcher.h" #include "mozilla/EventDispatcher.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/PresShell.h" #include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/SVGImageContext.h" #include "mozilla/SVGImageContext.h"
#include "Units.h" #include "Units.h"
#include "mozilla/layers/RenderRootStateManager.h" #include "mozilla/layers/RenderRootStateManager.h"
@ -419,6 +420,10 @@ ImgDrawResult nsImageBoxFrame::CreateWebRenderCommands(
if (aFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) { if (aFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
containerFlags |= imgIContainer::FLAG_SYNC_DECODE; containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
} }
if (StaticPrefs::image_svg_blob_image() &&
imgCon->GetType() == imgIContainer::TYPE_VECTOR) {
containerFlags |= imgIContainer::FLAG_RECORD_BLOB;
}
const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel(); const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect fillRect = LayoutDeviceRect fillRect =
@ -440,6 +445,20 @@ ImgDrawResult nsImageBoxFrame::CreateWebRenderCommands(
mozilla::wr::ImageRendering rendering = wr::ToImageRendering( mozilla::wr::ImageRendering rendering = wr::ToImageRendering(
nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame())); nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame()));
wr::LayoutRect fill = wr::ToLayoutRect(fillRect);
if (containerFlags & 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; gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey( Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(
aItem, container, aBuilder, aResources, rendering, aSc, size, Nothing()); aItem, container, aBuilder, aResources, rendering, aSc, size, Nothing());
@ -447,7 +466,6 @@ ImgDrawResult nsImageBoxFrame::CreateWebRenderCommands(
return result; return result;
} }
wr::LayoutRect fill = wr::ToLayoutRect(fillRect);
aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering, key.value()); aBuilder.PushImage(fill, fill, !BackfaceIsHidden(), rendering, key.value());
return result; return result;

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

@ -5469,6 +5469,12 @@
value: -1 value: -1
mirror: once mirror: once
# Whether we record SVG images as blobs or not.
- name: image.svg.blob-image
type: RelaxedAtomicBool
value: true
mirror: always
# Whether we attempt to decode WebP images or not. # Whether we attempt to decode WebP images or not.
- name: image.webp.enabled - name: image.webp.enabled
type: RelaxedAtomicBool type: RelaxedAtomicBool