diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index d21551baac8d..6d484476c072 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -403,7 +403,7 @@ void AsyncImagePipelineManager::ApplyAsyncImageForPipeline( wr::ToRoundedLayoutRect(aPipeline->mScBounds), nullptr, nullptr, &opacity, aPipeline->mScTransform.IsIdentity() ? nullptr : &aPipeline->mScTransform, wr::TransformStyle::Flat, nullptr, aPipeline->mMixBlendMode, - nsTArray(), true, + nsTArray(), true, // This is fine to do unconditionally because we only push images here. wr::RasterSpace::Screen()); diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp index ec9ee998a6e4..430feac5bf98 100644 --- a/gfx/layers/wr/StackingContextHelper.cpp +++ b/gfx/layers/wr/StackingContextHelper.cpp @@ -24,7 +24,7 @@ StackingContextHelper::StackingContextHelper() StackingContextHelper::StackingContextHelper( const StackingContextHelper& aParentSC, const ActiveScrolledRoot* aAsr, nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem, - wr::DisplayListBuilder& aBuilder, const nsTArray& aFilters, + wr::DisplayListBuilder& aBuilder, const nsTArray& aFilters, const LayoutDeviceRect& aBounds, const gfx::Matrix4x4* aBoundTransform, const wr::WrAnimationProperty* aAnimation, const float* aOpacityPtr, const gfx::Matrix4x4* aTransformPtr, const gfx::Matrix4x4* aPerspectivePtr, diff --git a/gfx/layers/wr/StackingContextHelper.h b/gfx/layers/wr/StackingContextHelper.h index e93bc4220262..0a2f049693a5 100644 --- a/gfx/layers/wr/StackingContextHelper.h +++ b/gfx/layers/wr/StackingContextHelper.h @@ -31,7 +31,7 @@ class MOZ_RAII StackingContextHelper { const StackingContextHelper& aParentSC, const ActiveScrolledRoot* aAsr, nsIFrame* aContainerFrame, nsDisplayItem* aContainerItem, wr::DisplayListBuilder& aBuilder, - const nsTArray& aFilters = nsTArray(), + const nsTArray& aFilters = nsTArray(), const LayoutDeviceRect& aBounds = LayoutDeviceRect(), const gfx::Matrix4x4* aBoundTransform = nullptr, const wr::WrAnimationProperty* aAnimation = nullptr, diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index d9e88fceee15..0b17a23d60bd 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -1432,7 +1432,7 @@ void WebRenderCommandBuilder::BuildWebRenderCommands( wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResourceUpdates, nsDisplayList* aDisplayList, nsDisplayListBuilder* aDisplayListBuilder, WebRenderScrollData& aScrollData, - wr::LayoutSize& aContentSize, const nsTArray& aFilters) { + wr::LayoutSize& aContentSize, const nsTArray& aFilters) { StackingContextHelper sc; aScrollData = WebRenderScrollData(mManager); MOZ_ASSERT(mLayerScrollData.empty()); diff --git a/gfx/layers/wr/WebRenderCommandBuilder.h b/gfx/layers/wr/WebRenderCommandBuilder.h index 21ebeeb09dd5..e3c68abe4277 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.h +++ b/gfx/layers/wr/WebRenderCommandBuilder.h @@ -57,7 +57,7 @@ class WebRenderCommandBuilder { nsDisplayListBuilder* aDisplayListBuilder, WebRenderScrollData& aScrollData, wr::LayoutSize& aContentSize, - const nsTArray& aFilters); + const nsTArray& aFilters); void PushOverrideForASR(const ActiveScrolledRoot* aASR, const wr::WrSpatialId& aSpatialId); diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 12c119310f95..8157cfe02025 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -246,7 +246,7 @@ void WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback, void WebRenderLayerManager::EndTransactionWithoutLayer( nsDisplayList* aDisplayList, nsDisplayListBuilder* aDisplayListBuilder, - const nsTArray& aFilters, + const nsTArray& aFilters, WebRenderBackgroundData* aBackground) { AUTO_PROFILER_TRACING("Paint", "RenderLayers"); diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index 7b1d5ba81017..8df091acdba7 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -79,7 +79,7 @@ class WebRenderLayerManager final : public LayerManager { EndTransactionFlags aFlags = END_DEFAULT) override; void EndTransactionWithoutLayer( nsDisplayList* aDisplayList, nsDisplayListBuilder* aDisplayListBuilder, - const nsTArray& aFilters = nsTArray(), + const nsTArray& aFilters = nsTArray(), WebRenderBackgroundData* aBackground = nullptr); virtual void EndTransaction( DrawPaintedLayerCallback aCallback, void* aCallbackData, diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 33b3358dd93d..91322e2818b2 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -676,7 +676,7 @@ Maybe DisplayListBuilder::PushStackingContext( const WrAnimationProperty* aAnimation, const float* aOpacity, const gfx::Matrix4x4* aTransform, wr::TransformStyle aTransformStyle, const gfx::Matrix4x4* aPerspective, const wr::MixBlendMode& aMixBlendMode, - const nsTArray& aFilters, bool aIsBackfaceVisible, + const nsTArray& aFilters, bool aIsBackfaceVisible, const wr::RasterSpace& aRasterSpace) { MOZ_ASSERT(mClipChainLeaf.isNothing(), "Non-empty leaf from clip chain given, but not used with SC!"); diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 1565d1a08be7..28259010421f 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -335,7 +335,7 @@ class DisplayListBuilder { const wr::WrAnimationProperty* aAnimation, const float* aOpacity, const gfx::Matrix4x4* aTransform, wr::TransformStyle aTransformStyle, const gfx::Matrix4x4* aPerspective, const wr::MixBlendMode& aMixBlendMode, - const nsTArray& aFilters, bool aIsBackfaceVisible, + const nsTArray& aFilters, bool aIsBackfaceVisible, const wr::RasterSpace& aRasterSpace); void PopStackingContext(bool aIsReferenceFrame); diff --git a/gfx/webrender_bindings/WebRenderTypes.h b/gfx/webrender_bindings/WebRenderTypes.h index 0750ff37c54a..3ded568991b5 100644 --- a/gfx/webrender_bindings/WebRenderTypes.h +++ b/gfx/webrender_bindings/WebRenderTypes.h @@ -771,7 +771,33 @@ struct BuiltDisplayList { wr::BuiltDisplayListDescriptor dl_desc; }; -extern WrClipId RootScrollNode(); +static inline wr::WrFilterOpType ToWrFilterOpType(uint32_t type) { + switch (type) { + case NS_STYLE_FILTER_BLUR: + return wr::WrFilterOpType::Blur; + case NS_STYLE_FILTER_BRIGHTNESS: + return wr::WrFilterOpType::Brightness; + case NS_STYLE_FILTER_CONTRAST: + return wr::WrFilterOpType::Contrast; + case NS_STYLE_FILTER_GRAYSCALE: + return wr::WrFilterOpType::Grayscale; + case NS_STYLE_FILTER_HUE_ROTATE: + return wr::WrFilterOpType::HueRotate; + case NS_STYLE_FILTER_INVERT: + return wr::WrFilterOpType::Invert; + case NS_STYLE_FILTER_OPACITY: + return wr::WrFilterOpType::Opacity; + case NS_STYLE_FILTER_SATURATE: + return wr::WrFilterOpType::Saturate; + case NS_STYLE_FILTER_SEPIA: + return wr::WrFilterOpType::Sepia; + case NS_STYLE_FILTER_DROP_SHADOW: + return wr::WrFilterOpType::DropShadow; + } + MOZ_ASSERT_UNREACHABLE("Tried to convert unknown filter type."); + return wr::WrFilterOpType::Grayscale; +} + // Corresponds to a clip id for a clip chain in webrender. Similar to // WrClipId but a separate struct so we don't get them mixed up in C++. diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index cc0d18fc4449..a14f579aa86c 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -477,6 +477,34 @@ pub struct WrAnimationProperty { id: u64, } +#[repr(u32)] +#[derive(Copy, Clone)] +pub enum WrFilterOpType { + Blur = 0, + Brightness = 1, + Contrast = 2, + Grayscale = 3, + HueRotate = 4, + Invert = 5, + Opacity = 6, + Saturate = 7, + Sepia = 8, + DropShadow = 9, + ColorMatrix = 10, + SrgbToLinear = 11, + LinearToSrgb = 12, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct WrFilterOp { + filter_type: WrFilterOpType, + argument: c_float, // holds radius for DropShadow; value for other filters + offset: LayoutVector2D, // only used for DropShadow + color: ColorF, // only used for DropShadow + matrix: [f32;20], // only used in ColorMatrix +} + /// cbindgen:derive-eq=false #[repr(C)] #[derive(Debug)] @@ -1884,7 +1912,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState, transform_style: TransformStyle, perspective: *const LayoutTransform, mix_blend_mode: MixBlendMode, - filters: *const FilterOp, + filters: *const WrFilterOp, filter_count: usize, is_backface_visible: bool, glyph_raster_space: RasterSpace, @@ -1893,7 +1921,23 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState, let c_filters = make_slice(filters, filter_count); let mut filters : Vec = c_filters.iter().map(|c_filter| { - *c_filter + match c_filter.filter_type { + WrFilterOpType::Blur => FilterOp::Blur(c_filter.argument), + WrFilterOpType::Brightness => FilterOp::Brightness(c_filter.argument), + WrFilterOpType::Contrast => FilterOp::Contrast(c_filter.argument), + WrFilterOpType::Grayscale => FilterOp::Grayscale(c_filter.argument), + WrFilterOpType::HueRotate => FilterOp::HueRotate(c_filter.argument), + WrFilterOpType::Invert => FilterOp::Invert(c_filter.argument), + WrFilterOpType::Opacity => FilterOp::Opacity(PropertyBinding::Value(c_filter.argument), c_filter.argument), + WrFilterOpType::Saturate => FilterOp::Saturate(c_filter.argument), + WrFilterOpType::Sepia => FilterOp::Sepia(c_filter.argument), + WrFilterOpType::DropShadow => FilterOp::DropShadow(c_filter.offset, + c_filter.argument, + c_filter.color), + WrFilterOpType::ColorMatrix => FilterOp::ColorMatrix(c_filter.matrix), + WrFilterOpType::SrgbToLinear => FilterOp::SrgbToLinear, + WrFilterOpType::LinearToSrgb => FilterOp::LinearToSrgb, + } }).collect(); let clip_node_id_ref = unsafe { clip_node_id.as_ref() }; diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index c7db50bd62a5..9a1413680c0d 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -244,6 +244,24 @@ enum class WrExternalImageType : uint32_t { Sentinel /* this must be last for serialization purposes. */ }; +enum class WrFilterOpType : uint32_t { + Blur = 0, + Brightness = 1, + Contrast = 2, + Grayscale = 3, + HueRotate = 4, + Invert = 5, + Opacity = 6, + Saturate = 7, + Sepia = 8, + DropShadow = 9, + ColorMatrix = 10, + SrgbToLinear = 11, + LinearToSrgb = 12, + + Sentinel /* this must be last for serialization purposes. */ +}; + enum class YuvColorSpace : uint32_t { Rec601 = 0, Rec709 = 1, @@ -899,385 +917,12 @@ struct TypedTransform3D { using LayoutTransform = TypedTransform3D; -struct PropertyBindingId { - IdNamespace namespace_; - uint32_t uid; - - bool operator==(const PropertyBindingId& aOther) const { - return namespace_ == aOther.namespace_ && - uid == aOther.uid; - } -}; - -/// A unique key that is used for connecting animated property -/// values to bindings in the display list. -template -struct PropertyBindingKey { - PropertyBindingId id; - - bool operator==(const PropertyBindingKey& aOther) const { - return id == aOther.id; - } -}; - -/// A binding property can either be a specific value -/// (the normal, non-animated case) or point to a binding location -/// to fetch the current value from. -/// Note that Binding has also a non-animated value, the value is -/// used for the case where the animation is still in-delay phase -/// (i.e. the animation doesn't produce any animation values). -template -struct PropertyBinding { - enum class Tag { - Value, - Binding, - - Sentinel /* this must be last for serialization purposes. */ - }; - - struct Value_Body { - T _0; - - bool operator==(const Value_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Binding_Body { - PropertyBindingKey _0; - T _1; - - bool operator==(const Binding_Body& aOther) const { - return _0 == aOther._0 && - _1 == aOther._1; - } - }; - - Tag tag; - union { - Value_Body value; - Binding_Body binding; - }; - - static PropertyBinding Value(const T &a0) { - PropertyBinding result; - result.value._0 = a0; - result.tag = Tag::Value; - return result; - } - - static PropertyBinding Binding(const PropertyBindingKey &a0, - const T &a1) { - PropertyBinding result; - result.binding._0 = a0; - result.binding._1 = a1; - result.tag = Tag::Binding; - return result; - } - - bool IsValue() const { - return tag == Tag::Value; - } - - bool IsBinding() const { - return tag == Tag::Binding; - } - - bool operator==(const PropertyBinding& aOther) const { - if (tag != aOther.tag) { - return false; - } - switch (tag) { - case Tag::Value: return value == aOther.value; - case Tag::Binding: return binding == aOther.binding; - default: return true; - } - } -}; - -struct FilterOp { - enum class Tag { - /// Filter that does no transformation of the colors, needed for - /// debug purposes only. - Identity, - Blur, - Brightness, - Contrast, - Grayscale, - HueRotate, - Invert, - Opacity, - Saturate, - Sepia, - DropShadow, - ColorMatrix, - SrgbToLinear, - LinearToSrgb, - - Sentinel /* this must be last for serialization purposes. */ - }; - - struct Blur_Body { - float _0; - - bool operator==(const Blur_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Brightness_Body { - float _0; - - bool operator==(const Brightness_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Contrast_Body { - float _0; - - bool operator==(const Contrast_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Grayscale_Body { - float _0; - - bool operator==(const Grayscale_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct HueRotate_Body { - float _0; - - bool operator==(const HueRotate_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Invert_Body { - float _0; - - bool operator==(const Invert_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Opacity_Body { - PropertyBinding _0; - float _1; - - bool operator==(const Opacity_Body& aOther) const { - return _0 == aOther._0 && - _1 == aOther._1; - } - }; - - struct Saturate_Body { - float _0; - - bool operator==(const Saturate_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct Sepia_Body { - float _0; - - bool operator==(const Sepia_Body& aOther) const { - return _0 == aOther._0; - } - }; - - struct DropShadow_Body { - LayoutVector2D _0; - float _1; - ColorF _2; - - bool operator==(const DropShadow_Body& aOther) const { - return _0 == aOther._0 && - _1 == aOther._1 && - _2 == aOther._2; - } - }; - - struct ColorMatrix_Body { - float _0[20]; - }; - - Tag tag; - union { - Blur_Body blur; - Brightness_Body brightness; - Contrast_Body contrast; - Grayscale_Body grayscale; - HueRotate_Body hue_rotate; - Invert_Body invert; - Opacity_Body opacity; - Saturate_Body saturate; - Sepia_Body sepia; - DropShadow_Body drop_shadow; - ColorMatrix_Body color_matrix; - }; - - static FilterOp Identity() { - FilterOp result; - result.tag = Tag::Identity; - return result; - } - - static FilterOp Blur(const float &a0) { - FilterOp result; - result.blur._0 = a0; - result.tag = Tag::Blur; - return result; - } - - static FilterOp Brightness(const float &a0) { - FilterOp result; - result.brightness._0 = a0; - result.tag = Tag::Brightness; - return result; - } - - static FilterOp Contrast(const float &a0) { - FilterOp result; - result.contrast._0 = a0; - result.tag = Tag::Contrast; - return result; - } - - static FilterOp Grayscale(const float &a0) { - FilterOp result; - result.grayscale._0 = a0; - result.tag = Tag::Grayscale; - return result; - } - - static FilterOp HueRotate(const float &a0) { - FilterOp result; - result.hue_rotate._0 = a0; - result.tag = Tag::HueRotate; - return result; - } - - static FilterOp Invert(const float &a0) { - FilterOp result; - result.invert._0 = a0; - result.tag = Tag::Invert; - return result; - } - - static FilterOp Opacity(const PropertyBinding &a0, - const float &a1) { - FilterOp result; - result.opacity._0 = a0; - result.opacity._1 = a1; - result.tag = Tag::Opacity; - return result; - } - - static FilterOp Saturate(const float &a0) { - FilterOp result; - result.saturate._0 = a0; - result.tag = Tag::Saturate; - return result; - } - - static FilterOp Sepia(const float &a0) { - FilterOp result; - result.sepia._0 = a0; - result.tag = Tag::Sepia; - return result; - } - - static FilterOp DropShadow(const LayoutVector2D &a0, - const float &a1, - const ColorF &a2) { - FilterOp result; - result.drop_shadow._0 = a0; - result.drop_shadow._1 = a1; - result.drop_shadow._2 = a2; - result.tag = Tag::DropShadow; - return result; - } - - static FilterOp ColorMatrix(const float (&a0)[20]) { - FilterOp result; - for (int i = 0; i < 20; i++) {result.color_matrix._0[i] = a0[i];} - result.tag = Tag::ColorMatrix; - return result; - } - - static FilterOp SrgbToLinear() { - FilterOp result; - result.tag = Tag::SrgbToLinear; - return result; - } - - static FilterOp LinearToSrgb() { - FilterOp result; - result.tag = Tag::LinearToSrgb; - return result; - } - - bool IsIdentity() const { - return tag == Tag::Identity; - } - - bool IsBlur() const { - return tag == Tag::Blur; - } - - bool IsBrightness() const { - return tag == Tag::Brightness; - } - - bool IsContrast() const { - return tag == Tag::Contrast; - } - - bool IsGrayscale() const { - return tag == Tag::Grayscale; - } - - bool IsHueRotate() const { - return tag == Tag::HueRotate; - } - - bool IsInvert() const { - return tag == Tag::Invert; - } - - bool IsOpacity() const { - return tag == Tag::Opacity; - } - - bool IsSaturate() const { - return tag == Tag::Saturate; - } - - bool IsSepia() const { - return tag == Tag::Sepia; - } - - bool IsDropShadow() const { - return tag == Tag::DropShadow; - } - - bool IsColorMatrix() const { - return tag == Tag::ColorMatrix; - } - - bool IsSrgbToLinear() const { - return tag == Tag::SrgbToLinear; - } - - bool IsLinearToSrgb() const { - return tag == Tag::LinearToSrgb; - } +struct WrFilterOp { + WrFilterOpType filter_type; + float argument; + LayoutVector2D offset; + ColorF color; + float matrix[20]; }; /// Configure whether the contents of a stacking context @@ -1944,7 +1589,7 @@ WrSpatialId wr_dp_push_stacking_context(WrState *aState, TransformStyle aTransformStyle, const LayoutTransform *aPerspective, MixBlendMode aMixBlendMode, - const FilterOp *aFilters, + const WrFilterOp *aFilters, uintptr_t aFilterCount, bool aIsBackfaceVisible, RasterSpace aGlyphRasterSpace) diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 519b809bd579..cf98cf7ad15a 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -6045,7 +6045,7 @@ void PresShell::Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion, bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor); WebRenderBackgroundData data(wr::ToLayoutRect(bounds), wr::ToColorF(ToDeviceColor(bgcolor))); - nsTArray wrFilters; + nsTArray wrFilters; MaybeSetupTransactionIdAllocator(layerManager, presContext); layerManager->AsWebRenderLayerManager()->EndTransactionWithoutLayer( diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 941bc229c6ab..29a9ae24bfcc 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -2616,12 +2616,14 @@ already_AddRefed nsDisplayList::PaintRoot( auto* wrManager = static_cast(layerManager.get()); nsIDocShell* docShell = presContext->GetDocShell(); - nsTArray wrFilters; + nsTArray wrFilters; gfx::Matrix5x4* colorMatrix = nsDocShell::Cast(docShell)->GetColorMatrix(); if (colorMatrix) { - wrFilters.AppendElement( - wr::FilterOp::ColorMatrix(colorMatrix->components)); + wr::WrFilterOp gs = {wr::WrFilterOpType::ColorMatrix}; + MOZ_ASSERT(sizeof(gs.matrix) == sizeof(colorMatrix->components)); + memcpy(&(gs.matrix), colorMatrix->components, sizeof(gs.matrix)); + wrFilters.AppendElement(gs); } wrManager->EndTransactionWithoutLayer(this, aBuilder, wrFilters); @@ -6068,7 +6070,7 @@ bool nsDisplayOpacity::CreateWebRenderCommands( animationsId, }; - nsTArray filters; + nsTArray filters; StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters, LayoutDeviceRect(), nullptr, animationsId ? &prop : nullptr, opacityForSC); @@ -6107,7 +6109,7 @@ bool nsDisplayBlendMode::CreateWebRenderCommands( const StackingContextHelper& aSc, mozilla::layers::RenderRootStateManager* aManager, nsDisplayListBuilder* aDisplayListBuilder) { - nsTArray filters; + nsTArray filters; StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters, LayoutDeviceRect(), nullptr, nullptr, nullptr, nullptr, nullptr, @@ -6339,7 +6341,7 @@ bool nsDisplayOwnLayer::CreateWebRenderCommands( prop.effect_type = wr::WrAnimationType::Transform; StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, - nsTArray(), LayoutDeviceRect(), + nsTArray(), LayoutDeviceRect(), nullptr, &prop); nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc, aManager, @@ -7856,7 +7858,7 @@ bool nsDisplayTransform::CreateWebRenderCommands( animationsId, }; - nsTArray filters; + nsTArray filters; Maybe deferredTransformItem; if (!mFrame->ChildrenHavePerspective()) { // If it has perspective, we create a new scroll data via the @@ -8463,7 +8465,7 @@ bool nsDisplayPerspective::CreateWebRenderCommands( nsIFrame* perspectiveFrame = mFrame->GetContainingBlock(nsIFrame::SKIP_SCROLLED_FRAME); - nsTArray filters; + nsTArray filters; StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, filters, LayoutDeviceRect(), nullptr, nullptr, nullptr, &transformForSC, &perspectiveMatrix, @@ -9060,7 +9062,7 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands( : Nothing(); layer.emplace(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, - /*aFilters: */ nsTArray(), + /*aFilters: */ nsTArray(), /*aBounds: */ bounds, /*aBoundTransform: */ nullptr, /*aAnimation: */ nullptr, @@ -9239,54 +9241,44 @@ static float ClampStdDeviation(float aStdDeviation) { } bool nsDisplayFilters::CreateWebRenderCSSFilters( - nsTArray& wrFilters) { + nsTArray& wrFilters) { // All CSS filters are supported by WebRender. SVG filters are not fully // supported, those use NS_STYLE_FILTER_URL and are handled separately. const nsTArray& filters = mFrame->StyleEffects()->mFilters; for (const nsStyleFilter& filter : filters) { switch (filter.GetType()) { case NS_STYLE_FILTER_BRIGHTNESS: - wrFilters.AppendElement(wr::FilterOp::Brightness( - filter.GetFilterParameter().GetFactorOrPercentValue())); - break; case NS_STYLE_FILTER_CONTRAST: - wrFilters.AppendElement(wr::FilterOp::Contrast( - filter.GetFilterParameter().GetFactorOrPercentValue())); - break; case NS_STYLE_FILTER_GRAYSCALE: - wrFilters.AppendElement(wr::FilterOp::Grayscale( - filter.GetFilterParameter().GetFactorOrPercentValue())); - break; case NS_STYLE_FILTER_INVERT: - wrFilters.AppendElement(wr::FilterOp::Invert( - filter.GetFilterParameter().GetFactorOrPercentValue())); - break; - case NS_STYLE_FILTER_OPACITY: { - float opacity = filter.GetFilterParameter().GetFactorOrPercentValue(); - wrFilters.AppendElement(wr::FilterOp::Opacity( - wr::PropertyBinding::Value(opacity), opacity)); - break; - } + case NS_STYLE_FILTER_OPACITY: case NS_STYLE_FILTER_SATURATE: - wrFilters.AppendElement(wr::FilterOp::Saturate( - filter.GetFilterParameter().GetFactorOrPercentValue())); - break; case NS_STYLE_FILTER_SEPIA: { - wrFilters.AppendElement(wr::FilterOp::Sepia( - filter.GetFilterParameter().GetFactorOrPercentValue())); + mozilla::wr::WrFilterOp filterOp = { + wr::ToWrFilterOpType(filter.GetType()), + filter.GetFilterParameter().GetFactorOrPercentValue(), + }; + wrFilters.AppendElement(filterOp); break; } case NS_STYLE_FILTER_HUE_ROTATE: { - wrFilters.AppendElement(wr::FilterOp::HueRotate( - (float)filter.GetFilterParameter().GetAngleValueInDegrees())); + mozilla::wr::WrFilterOp filterOp = { + wr::ToWrFilterOpType(filter.GetType()), + (float)filter.GetFilterParameter().GetAngleValueInDegrees(), + }; + wrFilters.AppendElement(filterOp); break; } case NS_STYLE_FILTER_BLUR: { float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - wrFilters.AppendElement(mozilla::wr::FilterOp::Blur(ClampStdDeviation( - NSAppUnitsToFloatPixels(filter.GetFilterParameter().GetCoordValue(), - appUnitsPerDevPixel)))); + mozilla::wr::WrFilterOp filterOp = { + wr::ToWrFilterOpType(filter.GetType()), + ClampStdDeviation(NSAppUnitsToFloatPixels( + filter.GetFilterParameter().GetCoordValue(), + appUnitsPerDevPixel)), + }; + wrFilters.AppendElement(filterOp); break; } case NS_STYLE_FILTER_DROP_SHADOW: { @@ -9303,18 +9295,19 @@ bool nsDisplayFilters::CreateWebRenderCSSFilters( nsCSSShadowItem* shadow = shadows->ShadowAt(0); nscolor color = shadow->mColor.CalcColor(mFrame); - auto filterOp = wr::FilterOp::DropShadow( + mozilla::wr::WrFilterOp filterOp = { + wr::ToWrFilterOpType(filter.GetType()), + NSAppUnitsToFloatPixels(shadow->mRadius, appUnitsPerDevPixel), { NSAppUnitsToFloatPixels(shadow->mXOffset, appUnitsPerDevPixel), NSAppUnitsToFloatPixels(shadow->mYOffset, appUnitsPerDevPixel), }, - NSAppUnitsToFloatPixels(shadow->mRadius, appUnitsPerDevPixel), { 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(filterOp); break; @@ -9341,7 +9334,7 @@ bool nsDisplayFilters::CreateWebRenderCommands( auto preFilterBounds = LayoutDeviceIntRect::Round( LayoutDeviceRect::FromAppUnits(mBounds, auPerDevPixel)); - nsTArray wrFilters; + nsTArray wrFilters; if (!CreateWebRenderCSSFilters(wrFilters) && !nsSVGIntegrationUtils::BuildWebRenderFilters( mFrame, preFilterBounds, wrFilters, postFilterBounds)) { diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index 7653ea22109a..749b8c3a1cec 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -6352,7 +6352,7 @@ class nsDisplayFilters : public nsDisplayEffectsBase { mozilla::layers::RenderRootStateManager* aManager, nsDisplayListBuilder* aDisplayListBuilder) override; - bool CreateWebRenderCSSFilters(nsTArray& wrFilters); + bool CreateWebRenderCSSFilters(nsTArray& wrFilters); private: // relative to mFrame diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 84148a4b4764..7e96ac5a847b 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -95,7 +95,7 @@ void nsFilterInstance::PaintFilteredFrame( bool nsFilterInstance::BuildWebRenderFilters( nsIFrame* aFilteredFrame, const LayoutDeviceIntRect& aPreFilterBounds, - nsTArray& aWrFilters, + nsTArray& aWrFilters, LayoutDeviceIntRect& aPostFilterBounds) { aWrFilters.Clear(); @@ -145,10 +145,12 @@ bool nsFilterInstance::BuildWebRenderFilters( bool primIsSrgb = primitive.OutputColorSpace() == gfx::ColorSpace::SRGB; if (srgb && !primIsSrgb) { - aWrFilters.AppendElement(wr::FilterOp::SrgbToLinear()); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::SrgbToLinear}; + aWrFilters.AppendElement(filterOp); srgb = false; } else if (!srgb && primIsSrgb) { - aWrFilters.AppendElement(wr::FilterOp::LinearToSrgb()); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::LinearToSrgb}; + aWrFilters.AppendElement(filterOp); srgb = true; } @@ -178,8 +180,8 @@ bool nsFilterInstance::BuildWebRenderFilters( if (attr.is()) { float opacity = attr.as().mOpacity; - aWrFilters.AppendElement(wr::FilterOp::Opacity( - wr::PropertyBinding::Value(opacity), opacity)); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::Opacity, opacity}; + aWrFilters.AppendElement(filterOp); } else if (attr.is()) { const ColorMatrixAttributes& attributes = attr.as(); @@ -211,7 +213,9 @@ bool nsFilterInstance::BuildWebRenderFilters( transposed[3], transposed[8], transposed[13], transposed[18], transposed[4], transposed[9], transposed[14], transposed[19]}; - aWrFilters.AppendElement(wr::FilterOp::ColorMatrix(matrix)); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::ColorMatrix}; + PodCopy(filterOp.matrix, matrix, 20); + aWrFilters.AppendElement(filterOp); } else if (attr.is()) { if (chainIsAffectedByPrimSubregion) { // There's a clip that needs to apply before the blur filter, but @@ -230,7 +234,8 @@ bool nsFilterInstance::BuildWebRenderFilters( float radius = stdDev.width; if (radius != 0.0) { - aWrFilters.AppendElement(wr::FilterOp::Blur(radius)); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::Blur, radius}; + aWrFilters.AppendElement(filterOp); } else { filterIsNoop = true; } @@ -247,11 +252,12 @@ bool nsFilterInstance::BuildWebRenderFilters( return false; } - wr::LayoutVector2D offset = {(float)shadow.mOffset.x, - (float)shadow.mOffset.y}; float radius = stdDev.width; - wr::FilterOp filterOp = - wr::FilterOp::DropShadow(offset, radius, wr::ToColorF(shadow.mColor)); + wr::WrFilterOp filterOp = { + wr::WrFilterOpType::DropShadow, + radius, + {(float)shadow.mOffset.x, (float)shadow.mOffset.y}, + wr::ToColorF(shadow.mColor)}; aWrFilters.AppendElement(filterOp); } else { @@ -259,8 +265,10 @@ bool nsFilterInstance::BuildWebRenderFilters( } if (filterIsNoop && aWrFilters.Length() > 0 && - (aWrFilters.LastElement().tag == wr::FilterOp::Tag::SrgbToLinear || - aWrFilters.LastElement().tag == wr::FilterOp::Tag::LinearToSrgb)) { + (aWrFilters.LastElement().filter_type == + wr::WrFilterOpType::SrgbToLinear || + aWrFilters.LastElement().filter_type == + wr::WrFilterOpType::LinearToSrgb)) { // We pushed a color space conversion filter in prevision of applying // another filter which turned out to be a no-op, so the conversion is // unnecessary. Remove it from the filter list. @@ -274,7 +282,8 @@ bool nsFilterInstance::BuildWebRenderFilters( } if (!srgb) { - aWrFilters.AppendElement(wr::FilterOp::LinearToSrgb()); + wr::WrFilterOp filterOp = {wr::WrFilterOpType::LinearToSrgb}; + aWrFilters.AppendElement(filterOp); } // Only adjust the post filter clip if we are able to render this without diff --git a/layout/svg/nsFilterInstance.h b/layout/svg/nsFilterInstance.h index 89a2dfcaecc9..480c25d4015a 100644 --- a/layout/svg/nsFilterInstance.h +++ b/layout/svg/nsFilterInstance.h @@ -125,7 +125,7 @@ class nsFilterInstance { static bool BuildWebRenderFilters( nsIFrame* aFilteredFrame, const mozilla::LayoutDeviceIntRect& aPreFilterBounds, - nsTArray& aWrFilters, + nsTArray& aWrFilters, mozilla::LayoutDeviceIntRect& aPostFilterBounds); private: diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 990e0f751b79..4d91363105e0 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -1096,7 +1096,7 @@ void nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams) { bool nsSVGIntegrationUtils::BuildWebRenderFilters( nsIFrame* aFilteredFrame, const mozilla::LayoutDeviceIntRect& aPreFilterBounds, - nsTArray& aWrFilters, + nsTArray& aWrFilters, mozilla::LayoutDeviceIntRect& aPostFilterBounds) { return nsFilterInstance::BuildWebRenderFilters( aFilteredFrame, aPreFilterBounds, aWrFilters, aPostFilterBounds); diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index bae671bd0b85..7490f03ee3df 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -198,7 +198,7 @@ class nsSVGIntegrationUtils final { static bool BuildWebRenderFilters( nsIFrame* aFilteredFrame, const mozilla::LayoutDeviceIntRect& aPreFilterBounds, - nsTArray& aWrFilters, + nsTArray& aWrFilters, mozilla::LayoutDeviceIntRect& aPostFilterBounds); /**