зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ad9e06d1e5
Коммит
4375178c34
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче