Bug 1578777 - Move CreateWebRenderCSSFilters() to nsSVGIntegrationUtils. r=jrmuizel

Depends on D46058

Differential Revision: https://phabricator.services.mozilla.com/D46059

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Botond Ballo 2019-09-16 21:54:16 +00:00
Родитель ad9e06d1e5
Коммит 4375178c34
3 изменённых файлов: 104 добавлений и 93 удалений

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

@ -10187,93 +10187,6 @@ void nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo) {
}
#endif
static float ClampStdDeviation(float aStdDeviation) {
// Cap software blur radius for performance reasons.
return std::min(std::max(0.0f, aStdDeviation), 100.0f);
}
static bool CreateWebRenderCSSFilters(Span<const StyleFilter> aFilters,
nsIFrame* aFrame,
WrFiltersHolder& aWrFilters) {
// All CSS filters are supported by WebRender. SVG filters are not fully
// supported, those use NS_STYLE_FILTER_URL and are handled separately.
// If there are too many filters to render, then just pretend that we
// succeeded, and don't render any of them.
if (aFilters.Length() >
StaticPrefs::gfx_webrender_max_filter_ops_per_chain()) {
return true;
}
aWrFilters.filters.SetCapacity(aFilters.Length());
auto& wrFilters = aWrFilters.filters;
for (const StyleFilter& filter : aFilters) {
switch (filter.tag) {
case StyleFilter::Tag::Brightness:
wrFilters.AppendElement(
wr::FilterOp::Brightness(filter.AsBrightness()));
break;
case StyleFilter::Tag::Contrast:
wrFilters.AppendElement(wr::FilterOp::Contrast(filter.AsContrast()));
break;
case StyleFilter::Tag::Grayscale:
wrFilters.AppendElement(wr::FilterOp::Grayscale(filter.AsGrayscale()));
break;
case StyleFilter::Tag::Invert:
wrFilters.AppendElement(wr::FilterOp::Invert(filter.AsInvert()));
break;
case StyleFilter::Tag::Opacity: {
float opacity = filter.AsOpacity();
wrFilters.AppendElement(wr::FilterOp::Opacity(
wr::PropertyBinding<float>::Value(opacity), opacity));
break;
}
case StyleFilter::Tag::Saturate:
wrFilters.AppendElement(wr::FilterOp::Saturate(filter.AsSaturate()));
break;
case StyleFilter::Tag::Sepia:
wrFilters.AppendElement(wr::FilterOp::Sepia(filter.AsSepia()));
break;
case StyleFilter::Tag::HueRotate: {
wrFilters.AppendElement(
wr::FilterOp::HueRotate(filter.AsHueRotate().ToDegrees()));
break;
}
case StyleFilter::Tag::Blur: {
// TODO(emilio): we should go directly from css pixels -> device pixels.
float appUnitsPerDevPixel =
aFrame->PresContext()->AppUnitsPerDevPixel();
wrFilters.AppendElement(mozilla::wr::FilterOp::Blur(
ClampStdDeviation(NSAppUnitsToFloatPixels(
filter.AsBlur().ToAppUnits(), appUnitsPerDevPixel))));
break;
}
case StyleFilter::Tag::DropShadow: {
float appUnitsPerDevPixel =
aFrame->PresContext()->AppUnitsPerDevPixel();
const StyleSimpleShadow& shadow = filter.AsDropShadow();
nscolor color = shadow.color.CalcColor(aFrame);
wr::Shadow wrShadow;
wrShadow.offset = {
NSAppUnitsToFloatPixels(shadow.horizontal.ToAppUnits(),
appUnitsPerDevPixel),
NSAppUnitsToFloatPixels(shadow.vertical.ToAppUnits(),
appUnitsPerDevPixel)};
wrShadow.blur_radius = NSAppUnitsToFloatPixels(shadow.blur.ToAppUnits(),
appUnitsPerDevPixel);
wrShadow.color = {NS_GET_R(color) / 255.0f, NS_GET_G(color) / 255.0f,
NS_GET_B(color) / 255.0f, NS_GET_A(color) / 255.0f};
wrFilters.AppendElement(wr::FilterOp::DropShadow(wrShadow));
break;
}
default:
return false;
}
}
return true;
}
already_AddRefed<Layer> nsDisplayBackdropRootContainer::BuildLayer(
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) {
@ -10317,7 +10230,8 @@ bool nsDisplayBackdropFilters::CanCreateWebRenderCommands(
WrFiltersHolder wrFilters;
Maybe<nsRect> filterClip;
auto filterChain = aFrame->StyleEffects()->mBackdropFilters.AsSpan();
return CreateWebRenderCSSFilters(filterChain, aFrame, wrFilters) ||
return nsSVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, aFrame,
wrFilters) ||
nsSVGIntegrationUtils::BuildWebRenderFilters(aFrame, filterChain,
wrFilters, filterClip);
}
@ -10331,7 +10245,8 @@ bool nsDisplayBackdropFilters::CreateWebRenderCommands(
WrFiltersHolder wrFilters;
Maybe<nsRect> filterClip;
auto filterChain = mFrame->StyleEffects()->mBackdropFilters.AsSpan();
if (!CreateWebRenderCSSFilters(filterChain, mFrame, wrFilters) &&
if (!nsSVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, mFrame,
wrFilters) &&
!nsSVGIntegrationUtils::BuildWebRenderFilters(mFrame, filterChain,
wrFilters, filterClip)) {
return false;
@ -10458,7 +10373,8 @@ bool nsDisplayFilters::CanCreateWebRenderCommands() {
WrFiltersHolder wrFilters;
Maybe<nsRect> filterClip;
auto filterChain = mFrame->StyleEffects()->mFilters.AsSpan();
return CreateWebRenderCSSFilters(filterChain, mFrame, wrFilters) ||
return nsSVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, mFrame,
wrFilters) ||
nsSVGIntegrationUtils::BuildWebRenderFilters(mFrame, filterChain,
wrFilters, filterClip);
}
@ -10474,7 +10390,8 @@ bool nsDisplayFilters::CreateWebRenderCommands(
WrFiltersHolder wrFilters;
Maybe<nsRect> filterClip;
auto filterChain = mFrame->StyleEffects()->mFilters.AsSpan();
if (!CreateWebRenderCSSFilters(filterChain, mFrame, wrFilters) &&
if (!nsSVGIntegrationUtils::CreateWebRenderCSSFilters(filterChain, mFrame,
wrFilters) &&
!nsSVGIntegrationUtils::BuildWebRenderFilters(mFrame, filterChain,
wrFilters, filterClip)) {
return false;

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

@ -1105,6 +1105,93 @@ void nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams) {
aParams.imgParams, opacity);
}
static float ClampStdDeviation(float aStdDeviation) {
// Cap software blur radius for performance reasons.
return std::min(std::max(0.0f, aStdDeviation), 100.0f);
}
bool nsSVGIntegrationUtils::CreateWebRenderCSSFilters(
Span<const StyleFilter> aFilters, nsIFrame* aFrame,
WrFiltersHolder& aWrFilters) {
// All CSS filters are supported by WebRender. SVG filters are not fully
// supported, those use NS_STYLE_FILTER_URL and are handled separately.
// If there are too many filters to render, then just pretend that we
// succeeded, and don't render any of them.
if (aFilters.Length() >
StaticPrefs::gfx_webrender_max_filter_ops_per_chain()) {
return true;
}
aWrFilters.filters.SetCapacity(aFilters.Length());
auto& wrFilters = aWrFilters.filters;
for (const StyleFilter& filter : aFilters) {
switch (filter.tag) {
case StyleFilter::Tag::Brightness:
wrFilters.AppendElement(
wr::FilterOp::Brightness(filter.AsBrightness()));
break;
case StyleFilter::Tag::Contrast:
wrFilters.AppendElement(wr::FilterOp::Contrast(filter.AsContrast()));
break;
case StyleFilter::Tag::Grayscale:
wrFilters.AppendElement(wr::FilterOp::Grayscale(filter.AsGrayscale()));
break;
case StyleFilter::Tag::Invert:
wrFilters.AppendElement(wr::FilterOp::Invert(filter.AsInvert()));
break;
case StyleFilter::Tag::Opacity: {
float opacity = filter.AsOpacity();
wrFilters.AppendElement(wr::FilterOp::Opacity(
wr::PropertyBinding<float>::Value(opacity), opacity));
break;
}
case StyleFilter::Tag::Saturate:
wrFilters.AppendElement(wr::FilterOp::Saturate(filter.AsSaturate()));
break;
case StyleFilter::Tag::Sepia:
wrFilters.AppendElement(wr::FilterOp::Sepia(filter.AsSepia()));
break;
case StyleFilter::Tag::HueRotate: {
wrFilters.AppendElement(
wr::FilterOp::HueRotate(filter.AsHueRotate().ToDegrees()));
break;
}
case StyleFilter::Tag::Blur: {
// TODO(emilio): we should go directly from css pixels -> device pixels.
float appUnitsPerDevPixel =
aFrame->PresContext()->AppUnitsPerDevPixel();
wrFilters.AppendElement(mozilla::wr::FilterOp::Blur(
ClampStdDeviation(NSAppUnitsToFloatPixels(
filter.AsBlur().ToAppUnits(), appUnitsPerDevPixel))));
break;
}
case StyleFilter::Tag::DropShadow: {
float appUnitsPerDevPixel =
aFrame->PresContext()->AppUnitsPerDevPixel();
const StyleSimpleShadow& shadow = filter.AsDropShadow();
nscolor color = shadow.color.CalcColor(aFrame);
wr::Shadow wrShadow;
wrShadow.offset = {
NSAppUnitsToFloatPixels(shadow.horizontal.ToAppUnits(),
appUnitsPerDevPixel),
NSAppUnitsToFloatPixels(shadow.vertical.ToAppUnits(),
appUnitsPerDevPixel)};
wrShadow.blur_radius = NSAppUnitsToFloatPixels(shadow.blur.ToAppUnits(),
appUnitsPerDevPixel);
wrShadow.color = {NS_GET_R(color) / 255.0f, NS_GET_G(color) / 255.0f,
NS_GET_B(color) / 255.0f, NS_GET_A(color) / 255.0f};
wrFilters.AppendElement(wr::FilterOp::DropShadow(wrShadow));
break;
}
default:
return false;
}
}
return true;
}
bool nsSVGIntegrationUtils::BuildWebRenderFilters(
nsIFrame* aFilteredFrame, Span<const StyleFilter> aFilters,
WrFiltersHolder& aWrFilters, Maybe<nsRect>& aPostFilterClip) {

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

@ -206,8 +206,15 @@ class nsSVGIntegrationUtils final {
static void PaintFilter(const PaintFramesParams& aParams);
/**
* Try to build WebRender filters for a frame if the filters applied to it are
* supported.
* Build WebRender filters for a frame with CSS filters applied to it.
*/
static bool CreateWebRenderCSSFilters(
mozilla::Span<const mozilla::StyleFilter> aFilters, nsIFrame* aFrame,
WrFiltersHolder& aWrFilters);
/**
* Try to build WebRender filters for a frame with SVG filters applied to it
* if the filters are supported.
*/
static bool BuildWebRenderFilters(
nsIFrame* aFilteredFrame,