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/PresShell.h"
#include "mozilla/PresShellInlines.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/SVGImageContext.h"
#include "mozilla/Unused.h"
@ -1998,6 +1999,10 @@ bool nsDisplayImage::CreateWebRenderCommands(
if (aDisplayListBuilder->UseHighQualityScaling()) {
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();
LayoutDeviceRect destRect(
@ -2021,13 +2026,25 @@ bool nsDisplayImage::CreateWebRenderCommands(
case ImgDrawResult::INCOMPLETE:
case ImgDrawResult::TEMPORARY_ERROR:
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;
ImgDrawResult newDrawResult = mPrevImage->GetImageContainerAtSize(
aManager->LayerManager(), decodeSize, svgContext, flags,
aManager->LayerManager(), decodeSize, svgContext, prevFlags,
getter_AddRefs(prevContainer));
if (prevContainer && newDrawResult == ImgDrawResult::SUCCESS) {
drawResult = newDrawResult;
container = std::move(prevContainer);
flags = prevFlags;
break;
}
@ -2054,8 +2071,13 @@ bool nsDisplayImage::CreateWebRenderCommands(
// 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) {
aManager->CommandBuilder().PushImage(this, container, aBuilder, aResources,
aSc, destRect, destRect);
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);
}
}
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, drawResult);

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

@ -24,6 +24,7 @@
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsStyleStructInlines.h"
#include "mozilla/StaticPrefs_image.h"
#include "mozilla/ISVGDisplayableFrame.h"
#include "mozilla/SVGIntegrationUtils.h"
#include "mozilla/SVGPaintServerFrame.h"
@ -588,6 +589,11 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
if (mFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
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{
nsPresContext::AppUnitsToIntCSSPixels(aDest.width),
@ -616,6 +622,15 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
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(
nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame()));
gfx::IntSize size;

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

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

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

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

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

@ -5469,6 +5469,12 @@
value: -1
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.
- name: image.webp.enabled
type: RelaxedAtomicBool