mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1505871. C++ code to get component transfer filter data into webrender. r=jrmuizel
Have to use a pointer/size pair to transfer the value list to rust. We use a "filter holder" that contains an nsTArray that owns the values.
This commit is contained in:
parent
ee7d7c1ee3
commit
b9d0354d8a
@ -12,6 +12,7 @@
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "Units.h"
|
||||
#include "nsSVGIntegrationUtils.h" // for WrFiltersHolder
|
||||
|
||||
class nsDisplayTransform;
|
||||
|
||||
|
@ -1425,7 +1425,7 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
wr::IpcResourceUpdateQueue& aResourceUpdates, nsDisplayList* aDisplayList,
|
||||
nsDisplayListBuilder* aDisplayListBuilder, WebRenderScrollData& aScrollData,
|
||||
wr::LayoutSize& aContentSize, nsTArray<wr::FilterOp>&& aFilters) {
|
||||
wr::LayoutSize& aContentSize, WrFiltersHolder&& aFilters) {
|
||||
AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_WRDisplayList);
|
||||
|
||||
StackingContextHelper sc;
|
||||
@ -1451,7 +1451,8 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
|
||||
presContext->Document()->IsTopLevelContentDocument();
|
||||
|
||||
wr::StackingContextParams params;
|
||||
params.mFilters = std::move(aFilters);
|
||||
params.mFilters = std::move(aFilters.filters);
|
||||
params.mFilterDatas = std::move(aFilters.filter_datas);
|
||||
params.animation = mZoomProp.ptrOr(nullptr);
|
||||
params.cache_tiles = isTopLevelContent;
|
||||
params.clip =
|
||||
|
@ -57,7 +57,7 @@ class WebRenderCommandBuilder {
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
WebRenderScrollData& aScrollData,
|
||||
wr::LayoutSize& aContentSize,
|
||||
nsTArray<wr::FilterOp>&& aFilters);
|
||||
WrFiltersHolder&& aFilters);
|
||||
|
||||
void PushOverrideForASR(const ActiveScrolledRoot* aASR,
|
||||
const wr::WrSpatialId& aSpatialId);
|
||||
|
@ -246,7 +246,7 @@ void WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
|
||||
|
||||
void WebRenderLayerManager::EndTransactionWithoutLayer(
|
||||
nsDisplayList* aDisplayList, nsDisplayListBuilder* aDisplayListBuilder,
|
||||
nsTArray<wr::FilterOp>&& aFilters, WebRenderBackgroundData* aBackground) {
|
||||
WrFiltersHolder&& aFilters, WebRenderBackgroundData* aBackground) {
|
||||
AUTO_PROFILER_TRACING("Paint", "RenderLayers", GRAPHICS);
|
||||
|
||||
// Since we don't do repeat transactions right now, just set the time
|
||||
|
@ -79,7 +79,7 @@ class WebRenderLayerManager final : public LayerManager {
|
||||
EndTransactionFlags aFlags = END_DEFAULT) override;
|
||||
void EndTransactionWithoutLayer(
|
||||
nsDisplayList* aDisplayList, nsDisplayListBuilder* aDisplayListBuilder,
|
||||
nsTArray<wr::FilterOp>&& aFilters = nsTArray<wr::FilterOp>(),
|
||||
WrFiltersHolder&& aFilters = WrFiltersHolder(),
|
||||
WebRenderBackgroundData* aBackground = nullptr);
|
||||
virtual void EndTransaction(
|
||||
DrawPaintedLayerCallback aCallback, void* aCallbackData,
|
||||
|
@ -690,7 +690,7 @@ Maybe<wr::WrSpatialId> DisplayListBuilder::PushStackingContext(
|
||||
auto spatialId = wr_dp_push_stacking_context(
|
||||
mWrState, aBounds, mCurrentSpaceAndClipChain.space, &aParams,
|
||||
maybeTransform, aParams.mFilters.Elements(), aParams.mFilters.Length(),
|
||||
aRasterSpace);
|
||||
aParams.mFilterDatas.Elements(), aParams.mFilterDatas.Length(), aRasterSpace);
|
||||
|
||||
return spatialId.id != 0 ? Some(spatialId) : Nothing();
|
||||
}
|
||||
|
@ -329,6 +329,7 @@ struct MOZ_STACK_CLASS StackingContextParams : public WrStackingContextParams {
|
||||
}
|
||||
|
||||
nsTArray<wr::FilterOp> mFilters;
|
||||
nsTArray<wr::WrFilterData> mFilterDatas;
|
||||
wr::LayoutRect mBounds = wr::ToLayoutRect(LayoutDeviceRect());
|
||||
const gfx::Matrix4x4* mBoundTransform = nullptr;
|
||||
const gfx::Matrix4x4* mTransformPtr = nullptr;
|
||||
|
@ -13,7 +13,7 @@ use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::ops::Range;
|
||||
use std::os::raw::{c_void, c_char};
|
||||
use std::os::raw::{c_void, c_char, c_float};
|
||||
#[cfg(target_os = "android")]
|
||||
use std::os::raw::{c_int};
|
||||
use gleam::gl;
|
||||
@ -489,6 +489,24 @@ impl ExternalImageHandler for WrExternalImageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
// Used for ComponentTransfer only
|
||||
pub struct WrFilterData {
|
||||
funcR_type: ComponentTransferFuncType,
|
||||
R_values: *mut c_float,
|
||||
R_values_count: usize,
|
||||
funcG_type: ComponentTransferFuncType,
|
||||
G_values: *mut c_float,
|
||||
G_values_count: usize,
|
||||
funcB_type: ComponentTransferFuncType,
|
||||
B_values: *mut c_float,
|
||||
B_values_count: usize,
|
||||
funcA_type: ComponentTransferFuncType,
|
||||
A_values: *mut c_float,
|
||||
A_values_count: usize,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
pub enum WrAnimationType {
|
||||
Transform = 0,
|
||||
@ -1952,6 +1970,8 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
||||
transform: *const LayoutTransform,
|
||||
filters: *const FilterOp,
|
||||
filter_count: usize,
|
||||
filter_datas: *const WrFilterData,
|
||||
filter_datas_count: usize,
|
||||
glyph_raster_space: RasterSpace,
|
||||
) -> WrSpatialId {
|
||||
debug_assert!(unsafe { !is_in_render_thread() });
|
||||
|
@ -6074,7 +6074,7 @@ void PresShell::Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
|
||||
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
|
||||
WebRenderBackgroundData data(wr::ToLayoutRect(bounds),
|
||||
wr::ToColorF(ToDeviceColor(bgcolor)));
|
||||
nsTArray<wr::FilterOp> wrFilters;
|
||||
WrFiltersHolder wrFilters;
|
||||
|
||||
MaybeSetupTransactionIdAllocator(layerManager, presContext);
|
||||
layerManager->AsWebRenderLayerManager()->EndTransactionWithoutLayer(
|
||||
|
@ -2604,11 +2604,11 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(
|
||||
auto* wrManager = static_cast<WebRenderLayerManager*>(layerManager.get());
|
||||
|
||||
nsIDocShell* docShell = presContext->GetDocShell();
|
||||
nsTArray<wr::FilterOp> wrFilters;
|
||||
WrFiltersHolder wrFilters;
|
||||
gfx::Matrix5x4* colorMatrix =
|
||||
nsDocShell::Cast(docShell)->GetColorMatrix();
|
||||
if (colorMatrix) {
|
||||
wrFilters.AppendElement(
|
||||
wrFilters.filters.AppendElement(
|
||||
wr::FilterOp::ColorMatrix(colorMatrix->components));
|
||||
}
|
||||
|
||||
@ -9321,7 +9321,7 @@ static float ClampStdDeviation(float aStdDeviation) {
|
||||
}
|
||||
|
||||
bool nsDisplayFilters::CreateWebRenderCSSFilters(
|
||||
nsTArray<mozilla::wr::FilterOp>& wrFilters) {
|
||||
WrFiltersHolder& 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<nsStyleFilter>& filters = mFrame->StyleEffects()->mFilters;
|
||||
@ -9331,50 +9331,50 @@ bool nsDisplayFilters::CreateWebRenderCSSFilters(
|
||||
if (filters.Length() > gfxPrefs::WebRenderMaxFilterOpsPerChain()) {
|
||||
return true;
|
||||
}
|
||||
wrFilters.SetCapacity(filters.Length());
|
||||
wrFilters.filters.SetCapacity(filters.Length());
|
||||
|
||||
for (const nsStyleFilter& filter : filters) {
|
||||
switch (filter.GetType()) {
|
||||
case NS_STYLE_FILTER_BRIGHTNESS:
|
||||
wrFilters.AppendElement(wr::FilterOp::Brightness(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Brightness(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
case NS_STYLE_FILTER_CONTRAST:
|
||||
wrFilters.AppendElement(wr::FilterOp::Contrast(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Contrast(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
case NS_STYLE_FILTER_GRAYSCALE:
|
||||
wrFilters.AppendElement(wr::FilterOp::Grayscale(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Grayscale(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
case NS_STYLE_FILTER_INVERT:
|
||||
wrFilters.AppendElement(wr::FilterOp::Invert(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Invert(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
case NS_STYLE_FILTER_OPACITY: {
|
||||
float opacity = filter.GetFilterParameter().GetFactorOrPercentValue();
|
||||
wrFilters.AppendElement(wr::FilterOp::Opacity(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Opacity(
|
||||
wr::PropertyBinding<float>::Value(opacity), opacity));
|
||||
break;
|
||||
}
|
||||
case NS_STYLE_FILTER_SATURATE:
|
||||
wrFilters.AppendElement(wr::FilterOp::Saturate(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Saturate(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
case NS_STYLE_FILTER_SEPIA: {
|
||||
wrFilters.AppendElement(wr::FilterOp::Sepia(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::Sepia(
|
||||
filter.GetFilterParameter().GetFactorOrPercentValue()));
|
||||
break;
|
||||
}
|
||||
case NS_STYLE_FILTER_HUE_ROTATE: {
|
||||
wrFilters.AppendElement(wr::FilterOp::HueRotate(
|
||||
wrFilters.filters.AppendElement(wr::FilterOp::HueRotate(
|
||||
(float)filter.GetFilterParameter().GetAngleValueInDegrees()));
|
||||
break;
|
||||
}
|
||||
case NS_STYLE_FILTER_BLUR: {
|
||||
float appUnitsPerDevPixel =
|
||||
mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
wrFilters.AppendElement(mozilla::wr::FilterOp::Blur(ClampStdDeviation(
|
||||
wrFilters.filters.AppendElement(mozilla::wr::FilterOp::Blur(ClampStdDeviation(
|
||||
NSAppUnitsToFloatPixels(filter.GetFilterParameter().GetCoordValue(),
|
||||
appUnitsPerDevPixel))));
|
||||
break;
|
||||
@ -9406,7 +9406,7 @@ bool nsDisplayFilters::CreateWebRenderCSSFilters(
|
||||
NS_GET_A(color) / 255.0f,
|
||||
});
|
||||
|
||||
wrFilters.AppendElement(filterOp);
|
||||
wrFilters.filters.AppendElement(filterOp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -9419,7 +9419,7 @@ bool nsDisplayFilters::CreateWebRenderCSSFilters(
|
||||
|
||||
bool nsDisplayFilters::CanCreateWebRenderCommands(
|
||||
nsDisplayListBuilder* aBuilder) {
|
||||
nsTArray<mozilla::wr::FilterOp> wrFilters;
|
||||
WrFiltersHolder wrFilters;
|
||||
Maybe<nsRect> filterClip;
|
||||
if (!CreateWebRenderCSSFilters(wrFilters) &&
|
||||
!nsSVGIntegrationUtils::BuildWebRenderFilters(mFrame, wrFilters,
|
||||
@ -9437,7 +9437,7 @@ bool nsDisplayFilters::CreateWebRenderCommands(
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
float auPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
nsTArray<mozilla::wr::FilterOp> wrFilters;
|
||||
WrFiltersHolder wrFilters;
|
||||
Maybe<nsRect> filterClip;
|
||||
if (!CreateWebRenderCSSFilters(wrFilters) &&
|
||||
!nsSVGIntegrationUtils::BuildWebRenderFilters(mFrame, wrFilters,
|
||||
@ -9458,7 +9458,8 @@ bool nsDisplayFilters::CreateWebRenderCommands(
|
||||
|
||||
float opacity = mFrame->StyleEffects()->mOpacity;
|
||||
wr::StackingContextParams params;
|
||||
params.mFilters = std::move(wrFilters);
|
||||
params.mFilters = std::move(wrFilters.filters);
|
||||
params.mFilterDatas = std::move(wrFilters.filter_datas);
|
||||
params.opacity = opacity != 1.0f && mHandleOpacity ? &opacity : nullptr;
|
||||
params.clip = clip;
|
||||
StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
|
||||
|
@ -64,6 +64,7 @@ class nsDisplayCompositorHitTestInfo;
|
||||
class nsDisplayScrollInfoLayer;
|
||||
class nsCaret;
|
||||
enum class nsDisplayOwnLayerFlags;
|
||||
struct WrFiltersHolder;
|
||||
|
||||
namespace mozilla {
|
||||
class FrameLayerBuilder;
|
||||
@ -6389,7 +6390,7 @@ class nsDisplayFilters : public nsDisplayEffectsBase {
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
bool CreateWebRenderCSSFilters(nsTArray<mozilla::wr::FilterOp>& wrFilters);
|
||||
bool CreateWebRenderCSSFilters(WrFiltersHolder& wrFilters);
|
||||
|
||||
private:
|
||||
// relative to mFrame
|
||||
|
@ -95,10 +95,32 @@ void nsFilterInstance::PaintFilteredFrame(
|
||||
}
|
||||
}
|
||||
|
||||
static mozilla::wr::ComponentTransferFuncType
|
||||
FuncTypeToWr(uint8_t aFuncType) {
|
||||
switch (aFuncType) {
|
||||
case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY:
|
||||
return mozilla::wr::ComponentTransferFuncType::Identity;
|
||||
case SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
|
||||
return mozilla::wr::ComponentTransferFuncType::Table;
|
||||
case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
|
||||
return mozilla::wr::ComponentTransferFuncType::Discrete;
|
||||
case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
|
||||
return mozilla::wr::ComponentTransferFuncType::Linear;
|
||||
case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
|
||||
return mozilla::wr::ComponentTransferFuncType::Gamma;
|
||||
default:
|
||||
MOZ_ASSERT(false, "unknown func type?");
|
||||
}
|
||||
MOZ_ASSERT(false, "unknown func type?");
|
||||
return mozilla::wr::ComponentTransferFuncType::Identity;
|
||||
}
|
||||
|
||||
bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
nsTArray<wr::FilterOp>& aWrFilters,
|
||||
WrFiltersHolder& aWrFilters,
|
||||
Maybe<nsRect>& aPostFilterClip) {
|
||||
aWrFilters.Clear();
|
||||
aWrFilters.filters.Clear();
|
||||
aWrFilters.filter_datas.Clear();
|
||||
aWrFilters.values.Clear();
|
||||
|
||||
auto& filterChain = aFilteredFrame->StyleEffects()->mFilters;
|
||||
UniquePtr<UserSpaceMetrics> metrics =
|
||||
@ -162,9 +184,9 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
bool previousSrgb = srgb;
|
||||
bool primNeedsSrgb = primitive.InputColorSpace(0) == gfx::ColorSpace::SRGB;
|
||||
if (srgb && !primNeedsSrgb) {
|
||||
aWrFilters.AppendElement(wr::FilterOp::SrgbToLinear());
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::SrgbToLinear());
|
||||
} else if (!srgb && primNeedsSrgb) {
|
||||
aWrFilters.AppendElement(wr::FilterOp::LinearToSrgb());
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::LinearToSrgb());
|
||||
}
|
||||
srgb = primitive.OutputColorSpace() == gfx::ColorSpace::SRGB;
|
||||
|
||||
@ -174,7 +196,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
|
||||
if (attr.is<OpacityAttributes>()) {
|
||||
float opacity = attr.as<OpacityAttributes>().mOpacity;
|
||||
aWrFilters.AppendElement(wr::FilterOp::Opacity(
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::Opacity(
|
||||
wr::PropertyBinding<float>::Value(opacity), opacity));
|
||||
} else if (attr.is<ColorMatrixAttributes>()) {
|
||||
const ColorMatrixAttributes& attributes =
|
||||
@ -207,7 +229,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
transposed[3], transposed[8], transposed[13], transposed[18],
|
||||
transposed[4], transposed[9], transposed[14], transposed[19]};
|
||||
|
||||
aWrFilters.AppendElement(wr::FilterOp::ColorMatrix(matrix));
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::ColorMatrix(matrix));
|
||||
} else if (attr.is<GaussianBlurAttributes>()) {
|
||||
if (finalClip) {
|
||||
// There's a clip that needs to apply before the blur filter, but
|
||||
@ -226,7 +248,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
|
||||
float radius = stdDev.width;
|
||||
if (radius != 0.0) {
|
||||
aWrFilters.AppendElement(wr::FilterOp::Blur(radius));
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::Blur(radius));
|
||||
} else {
|
||||
filterIsNoop = true;
|
||||
}
|
||||
@ -255,14 +277,60 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
wr::FilterOp filterOp = wr::FilterOp::DropShadow(
|
||||
offset, radius, wr::ToColorF(ToDeviceColor(color)));
|
||||
|
||||
aWrFilters.AppendElement(filterOp);
|
||||
aWrFilters.filters.AppendElement(filterOp);
|
||||
} else if (attr.is<ComponentTransferAttributes>()) {
|
||||
const ComponentTransferAttributes& attributes =
|
||||
attr.as<ComponentTransferAttributes>();
|
||||
|
||||
size_t numValues = attributes.mValues[0].Length() +
|
||||
attributes.mValues[1].Length() + attributes.mValues[2].Length() +
|
||||
attributes.mValues[3].Length();
|
||||
if (numValues > 1024) {
|
||||
// Depending on how the wr shaders are implemented we may need to
|
||||
// limit the total number of values.
|
||||
return false;
|
||||
}
|
||||
|
||||
wr::FilterOp filterOp = {wr::FilterOp::Tag::ComponentTransfer};
|
||||
wr::WrFilterData filterData;
|
||||
aWrFilters.values.AppendElement(nsTArray<float>());
|
||||
nsTArray<float>* values = &aWrFilters.values[aWrFilters.values.Length()-1];
|
||||
values->SetCapacity(numValues);
|
||||
|
||||
filterData.funcR_type = FuncTypeToWr(attributes.mTypes[0]);
|
||||
size_t R_startindex = values->Length();
|
||||
values->AppendElements(attributes.mValues[0]);
|
||||
filterData.R_values_count = attributes.mValues[0].Length();
|
||||
|
||||
filterData.funcG_type = FuncTypeToWr(attributes.mTypes[1]);
|
||||
size_t G_startindex = values->Length();
|
||||
values->AppendElements(attributes.mValues[1]);
|
||||
filterData.G_values_count = attributes.mValues[1].Length();
|
||||
|
||||
filterData.funcB_type = FuncTypeToWr(attributes.mTypes[2]);
|
||||
size_t B_startindex = values->Length();
|
||||
values->AppendElements(attributes.mValues[2]);
|
||||
filterData.B_values_count = attributes.mValues[2].Length();
|
||||
|
||||
filterData.funcA_type = FuncTypeToWr(attributes.mTypes[3]);
|
||||
size_t A_startindex = values->Length();
|
||||
values->AppendElements(attributes.mValues[3]);
|
||||
filterData.A_values_count = attributes.mValues[3].Length();
|
||||
|
||||
filterData.R_values = filterData.R_values_count > 0 ? &((*values)[R_startindex]) : nullptr;
|
||||
filterData.G_values = filterData.G_values_count > 0 ? &((*values)[G_startindex]) : nullptr;
|
||||
filterData.B_values = filterData.B_values_count > 0 ? &((*values)[B_startindex]) : nullptr;
|
||||
filterData.A_values = filterData.A_values_count > 0 ? &((*values)[A_startindex]) : nullptr;
|
||||
|
||||
aWrFilters.filters.AppendElement(filterOp);
|
||||
aWrFilters.filter_datas.AppendElement(filterData);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filterIsNoop && aWrFilters.Length() > 0 &&
|
||||
(aWrFilters.LastElement().tag == wr::FilterOp::Tag::SrgbToLinear ||
|
||||
aWrFilters.LastElement().tag == wr::FilterOp::Tag::LinearToSrgb)) {
|
||||
if (filterIsNoop && aWrFilters.filters.Length() > 0 &&
|
||||
(aWrFilters.filters.LastElement().tag == wr::FilterOp::Tag::SrgbToLinear ||
|
||||
aWrFilters.filters.LastElement().tag == wr::FilterOp::Tag::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.
|
||||
@ -270,7 +338,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
// css/filter-effects/filter-scale-001.html for which the needless
|
||||
// sRGB->linear->no-op->sRGB roundtrip introduces a slight error and we
|
||||
// cannot add fuzziness to the test.
|
||||
Unused << aWrFilters.PopLastElement();
|
||||
Unused << aWrFilters.filters.PopLastElement();
|
||||
srgb = previousSrgb;
|
||||
}
|
||||
|
||||
@ -285,7 +353,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
}
|
||||
|
||||
if (!srgb) {
|
||||
aWrFilters.AppendElement(wr::FilterOp::LinearToSrgb());
|
||||
aWrFilters.filters.AppendElement(wr::FilterOp::LinearToSrgb());
|
||||
}
|
||||
|
||||
if (finalClip) {
|
||||
|
@ -123,7 +123,7 @@ class nsFilterInstance {
|
||||
* supported.
|
||||
*/
|
||||
static bool BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
nsTArray<mozilla::wr::FilterOp>& aWrFilters,
|
||||
WrFiltersHolder& aWrFilters,
|
||||
mozilla::Maybe<nsRect>& aPostFilterClip);
|
||||
|
||||
private:
|
||||
|
@ -1086,7 +1086,7 @@ void nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams) {
|
||||
}
|
||||
|
||||
bool nsSVGIntegrationUtils::BuildWebRenderFilters(
|
||||
nsIFrame* aFilteredFrame, nsTArray<mozilla::wr::FilterOp>& aWrFilters,
|
||||
nsIFrame* aFilteredFrame, WrFiltersHolder& aWrFilters,
|
||||
Maybe<nsRect>& aPostFilterClip) {
|
||||
return nsFilterInstance::BuildWebRenderFilters(aFilteredFrame, aWrFilters,
|
||||
aPostFilterClip);
|
||||
|
@ -34,6 +34,13 @@ class LayerManager;
|
||||
struct nsPoint;
|
||||
struct nsSize;
|
||||
|
||||
struct WrFiltersHolder {
|
||||
nsTArray<mozilla::wr::FilterOp> filters;
|
||||
nsTArray<mozilla::wr::WrFilterData> filter_datas;
|
||||
// This exists just to own the values long enough for them to be copied into rust.
|
||||
nsTArray<nsTArray<float>> values;
|
||||
};
|
||||
|
||||
/**
|
||||
* Integration of SVG effects (clipPath clipping, masking and filters) into
|
||||
* regular display list based painting and hit-testing.
|
||||
@ -196,7 +203,7 @@ class nsSVGIntegrationUtils final {
|
||||
* supported.
|
||||
*/
|
||||
static bool BuildWebRenderFilters(nsIFrame* aFilteredFrame,
|
||||
nsTArray<mozilla::wr::FilterOp>& aWrFilters,
|
||||
WrFiltersHolder& aWrFilters,
|
||||
mozilla::Maybe<nsRect>& aPostFilterClip);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user