зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1365972 - Add initial WebRender support for nsDisplayFilter. r=rhunt, r=mattwoodrow
This commit is contained in:
Родитель
1d80223f3d
Коммит
7d937678f4
|
@ -2250,6 +2250,12 @@ public:
|
||||||
return mEventRegionsOverride;
|
return mEventRegionsOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetFilterChain(nsTArray<CSSFilter>&& aFilterChain) {
|
||||||
|
mFilterChain = aFilterChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsTArray<CSSFilter>& GetFilterChain() { return mFilterChain; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class ReadbackProcessor;
|
friend class ReadbackProcessor;
|
||||||
|
|
||||||
|
@ -2336,6 +2342,7 @@ protected:
|
||||||
// the intermediate surface.
|
// the intermediate surface.
|
||||||
bool mChildrenChanged;
|
bool mChildrenChanged;
|
||||||
EventRegionsOverride mEventRegionsOverride;
|
EventRegionsOverride mEventRegionsOverride;
|
||||||
|
nsTArray<CSSFilter> mFilterChain;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "LayersTypes.h"
|
||||||
|
|
||||||
|
#include "nsStyleStruct.h" // for nsStyleFilter
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace layers {
|
||||||
|
|
||||||
|
CSSFilter ToCSSFilter(const nsStyleFilter& filter)
|
||||||
|
{
|
||||||
|
switch (filter.GetType()) {
|
||||||
|
case NS_STYLE_FILTER_BRIGHTNESS: {
|
||||||
|
return {
|
||||||
|
CSSFilterType::BRIGHTNESS,
|
||||||
|
filter.GetFilterParameter().GetFactorOrPercentValue(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case NS_STYLE_FILTER_CONTRAST: {
|
||||||
|
return {
|
||||||
|
CSSFilterType::CONTRAST,
|
||||||
|
filter.GetFilterParameter().GetFactorOrPercentValue(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// All other filter types should be prevented by the code which converts
|
||||||
|
// display items into layers.
|
||||||
|
default:
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Tried to convert an unsupported filter");
|
||||||
|
return { CSSFilterType::CONTRAST, 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace layers
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace android {
|
||||||
class MOZ_EXPORT GraphicBuffer;
|
class MOZ_EXPORT GraphicBuffer;
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
struct nsStyleFilter;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
@ -309,6 +311,25 @@ enum class ScrollDirection : uint32_t {
|
||||||
SENTINEL /* for IPC serialization */
|
SENTINEL /* for IPC serialization */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CSSFilterType : int8_t {
|
||||||
|
BLUR,
|
||||||
|
BRIGHTNESS,
|
||||||
|
CONTRAST,
|
||||||
|
GRAYSCALE,
|
||||||
|
HUE_ROTATE,
|
||||||
|
INVERT,
|
||||||
|
OPACITY,
|
||||||
|
SATURATE,
|
||||||
|
SEPIA,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CSSFilter {
|
||||||
|
CSSFilterType type;
|
||||||
|
float argument;
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSFilter ToCSSFilter(const nsStyleFilter& filter);
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -383,6 +383,7 @@ UNIFIED_SOURCES += [
|
||||||
'LayerScope.cpp',
|
'LayerScope.cpp',
|
||||||
'LayersLogging.cpp',
|
'LayersLogging.cpp',
|
||||||
'LayerSorter.cpp',
|
'LayerSorter.cpp',
|
||||||
|
'LayersTypes.cpp',
|
||||||
'opengl/CompositingRenderTargetOGL.cpp',
|
'opengl/CompositingRenderTargetOGL.cpp',
|
||||||
'opengl/CompositorOGL.cpp',
|
'opengl/CompositorOGL.cpp',
|
||||||
'opengl/GLBlitTextureImageHelper.cpp',
|
'opengl/GLBlitTextureImageHelper.cpp',
|
||||||
|
|
|
@ -20,16 +20,19 @@ StackingContextHelper::StackingContextHelper()
|
||||||
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
|
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
|
||||||
wr::DisplayListBuilder& aBuilder,
|
wr::DisplayListBuilder& aBuilder,
|
||||||
WebRenderLayer* aLayer,
|
WebRenderLayer* aLayer,
|
||||||
const Maybe<gfx::Matrix4x4>& aTransform)
|
const Maybe<gfx::Matrix4x4>& aTransform,
|
||||||
|
const nsTArray<WrFilterOp>& aFilters)
|
||||||
: mBuilder(&aBuilder)
|
: mBuilder(&aBuilder)
|
||||||
{
|
{
|
||||||
WrRect scBounds = aParentSC.ToRelativeWrRect(aLayer->BoundsForStackingContext());
|
WrRect scBounds = aParentSC.ToRelativeWrRect(aLayer->BoundsForStackingContext());
|
||||||
Layer* layer = aLayer->GetLayer();
|
Layer* layer = aLayer->GetLayer();
|
||||||
mTransform = aTransform.valueOr(layer->GetTransform());
|
mTransform = aTransform.valueOr(layer->GetTransform());
|
||||||
|
|
||||||
float opacity = 1.0f;
|
float opacity = 1.0f;
|
||||||
mBuilder->PushStackingContext(scBounds, 0, &opacity,
|
mBuilder->PushStackingContext(scBounds, 0, &opacity,
|
||||||
mTransform.IsIdentity() ? nullptr : &mTransform,
|
mTransform.IsIdentity() ? nullptr : &mTransform,
|
||||||
wr::ToWrMixBlendMode(layer->GetMixBlendMode()));
|
wr::ToWrMixBlendMode(layer->GetMixBlendMode()),
|
||||||
|
aFilters);
|
||||||
mOrigin = aLayer->Bounds().TopLeft();
|
mOrigin = aLayer->Bounds().TopLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,18 +41,21 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
|
||||||
WebRenderLayer* aLayer,
|
WebRenderLayer* aLayer,
|
||||||
uint64_t aAnimationsId,
|
uint64_t aAnimationsId,
|
||||||
float* aOpacityPtr,
|
float* aOpacityPtr,
|
||||||
gfx::Matrix4x4* aTransformPtr)
|
gfx::Matrix4x4* aTransformPtr,
|
||||||
|
const nsTArray<WrFilterOp>& aFilters)
|
||||||
: mBuilder(&aBuilder)
|
: mBuilder(&aBuilder)
|
||||||
{
|
{
|
||||||
WrRect scBounds = aParentSC.ToRelativeWrRect(aLayer->BoundsForStackingContext());
|
WrRect scBounds = aParentSC.ToRelativeWrRect(aLayer->BoundsForStackingContext());
|
||||||
if (aTransformPtr) {
|
if (aTransformPtr) {
|
||||||
mTransform = *aTransformPtr;
|
mTransform = *aTransformPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mBuilder->PushStackingContext(scBounds,
|
mBuilder->PushStackingContext(scBounds,
|
||||||
aAnimationsId,
|
aAnimationsId,
|
||||||
aOpacityPtr,
|
aOpacityPtr,
|
||||||
aTransformPtr,
|
aTransformPtr,
|
||||||
wr::ToWrMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()));
|
wr::ToWrMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()),
|
||||||
|
aFilters);
|
||||||
mOrigin = aLayer->Bounds().TopLeft();
|
mOrigin = aLayer->Bounds().TopLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ public:
|
||||||
StackingContextHelper(const StackingContextHelper& aParentSC,
|
StackingContextHelper(const StackingContextHelper& aParentSC,
|
||||||
wr::DisplayListBuilder& aBuilder,
|
wr::DisplayListBuilder& aBuilder,
|
||||||
WebRenderLayer* aLayer,
|
WebRenderLayer* aLayer,
|
||||||
const Maybe<gfx::Matrix4x4>& aTransform = Nothing());
|
const Maybe<gfx::Matrix4x4>& aTransform = Nothing(),
|
||||||
|
const nsTArray<WrFilterOp>& aFilters = nsTArray<WrFilterOp>());
|
||||||
// Alternate constructor which invokes the version of PushStackingContext
|
// Alternate constructor which invokes the version of PushStackingContext
|
||||||
// for animations.
|
// for animations.
|
||||||
StackingContextHelper(const StackingContextHelper& aParentSC,
|
StackingContextHelper(const StackingContextHelper& aParentSC,
|
||||||
|
@ -39,7 +40,8 @@ public:
|
||||||
WebRenderLayer* aLayer,
|
WebRenderLayer* aLayer,
|
||||||
uint64_t aAnimationsId,
|
uint64_t aAnimationsId,
|
||||||
float* aOpacityPtr,
|
float* aOpacityPtr,
|
||||||
gfx::Matrix4x4* aTransformPtr);
|
gfx::Matrix4x4* aTransformPtr,
|
||||||
|
const nsTArray<WrFilterOp>& aFilters = nsTArray<WrFilterOp>());
|
||||||
// This version of the constructor should only be used at the root level
|
// This version of the constructor should only be used at the root level
|
||||||
// of the tree, so that we have a StackingContextHelper to pass down into
|
// of the tree, so that we have a StackingContextHelper to pass down into
|
||||||
// the RenderLayer traversal, but don't actually want it to push a stacking
|
// the RenderLayer traversal, but don't actually want it to push a stacking
|
||||||
|
|
|
@ -275,7 +275,8 @@ WebRenderCompositableHolder::ApplyAsyncImages(wr::WebRenderAPI* aApi)
|
||||||
0,
|
0,
|
||||||
&opacity,
|
&opacity,
|
||||||
holder->mScTransform.IsIdentity() ? nullptr : &holder->mScTransform,
|
holder->mScTransform.IsIdentity() ? nullptr : &holder->mScTransform,
|
||||||
holder->mMixBlendMode);
|
holder->mMixBlendMode,
|
||||||
|
nsTArray<WrFilterOp>());
|
||||||
|
|
||||||
LayerRect rect(0, 0, holder->mCurrentTexture->GetSize().width, holder->mCurrentTexture->GetSize().height);
|
LayerRect rect(0, 0, holder->mCurrentTexture->GetSize().width, holder->mCurrentTexture->GetSize().height);
|
||||||
if (holder->mScaleToSize.isSome()) {
|
if (holder->mScaleToSize.isSome()) {
|
||||||
|
|
|
@ -114,8 +114,13 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
|
||||||
transformForSC = nullptr;
|
transformForSC = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsTArray<WrFilterOp> filters;
|
||||||
|
for (const CSSFilter& filter : this->GetFilterChain()) {
|
||||||
|
filters.AppendElement(wr::ToWrFilterOp(filter));
|
||||||
|
}
|
||||||
|
|
||||||
ScrollingLayersHelper scroller(this, aBuilder, aSc);
|
ScrollingLayersHelper scroller(this, aBuilder, aSc);
|
||||||
StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC);
|
StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC, filters);
|
||||||
|
|
||||||
LayerRect rect = Bounds();
|
LayerRect rect = Bounds();
|
||||||
DumpLayerInfo("ContainerLayer", rect);
|
DumpLayerInfo("ContainerLayer", rect);
|
||||||
|
|
|
@ -504,6 +504,7 @@ private:
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, gfxPrefs::OverrideBase_WebRender());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.caret-layers", LayersAllowCaretLayers, gfxPrefs::OverrideBase_WebRender());
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.columnRule-layers", LayersAllowColumnRuleLayers, gfxPrefs::OverrideBase_WebRender());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.columnRule-layers", LayersAllowColumnRuleLayers, gfxPrefs::OverrideBase_WebRender());
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, gfxPrefs::OverrideBase_WebRender());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, gfxPrefs::OverrideBase_WebRender());
|
||||||
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.filter-layers", LayersAllowFilterLayers, gfxPrefs::OverrideBase_WebRender());
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, gfxPrefs::OverrideBase_WebRendest());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.image-layers", LayersAllowImageLayers, gfxPrefs::OverrideBase_WebRendest());
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
|
||||||
DECL_OVERRIDE_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, gfxPrefs::OverrideBase_WebRender());
|
DECL_OVERRIDE_PREF(Live, "layers.advanced.solid-color", LayersAllowSolidColorLayers, gfxPrefs::OverrideBase_WebRender());
|
||||||
|
|
|
@ -556,7 +556,8 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
|
||||||
const uint64_t& aAnimationId,
|
const uint64_t& aAnimationId,
|
||||||
const float* aOpacity,
|
const float* aOpacity,
|
||||||
const gfx::Matrix4x4* aTransform,
|
const gfx::Matrix4x4* aTransform,
|
||||||
const WrMixBlendMode& aMixBlendMode)
|
const WrMixBlendMode& aMixBlendMode,
|
||||||
|
const nsTArray<WrFilterOp>& aFilters)
|
||||||
{
|
{
|
||||||
WrMatrix matrix;
|
WrMatrix matrix;
|
||||||
if (aTransform) {
|
if (aTransform) {
|
||||||
|
@ -566,7 +567,8 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
|
||||||
WRDL_LOG("PushStackingContext b=%s t=%s\n", Stringify(aBounds).c_str(),
|
WRDL_LOG("PushStackingContext b=%s t=%s\n", Stringify(aBounds).c_str(),
|
||||||
aTransform ? Stringify(*aTransform).c_str() : "none");
|
aTransform ? Stringify(*aTransform).c_str() : "none");
|
||||||
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
|
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
|
||||||
maybeTransform, aMixBlendMode);
|
maybeTransform, aMixBlendMode,
|
||||||
|
aFilters.Elements(), aFilters.Length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -150,7 +150,8 @@ public:
|
||||||
const uint64_t& aAnimationId,
|
const uint64_t& aAnimationId,
|
||||||
const float* aOpacity,
|
const float* aOpacity,
|
||||||
const gfx::Matrix4x4* aTransform,
|
const gfx::Matrix4x4* aTransform,
|
||||||
const WrMixBlendMode& aMixBlendMode);
|
const WrMixBlendMode& aMixBlendMode,
|
||||||
|
const nsTArray<WrFilterOp>& aFilters);
|
||||||
void PopStackingContext();
|
void PopStackingContext();
|
||||||
|
|
||||||
void PushClip(const WrRect& aClipRect,
|
void PushClip(const WrRect& aClipRect,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/gfx/Matrix.h"
|
#include "mozilla/gfx/Matrix.h"
|
||||||
#include "mozilla/gfx/Types.h"
|
#include "mozilla/gfx/Types.h"
|
||||||
#include "mozilla/gfx/Tools.h"
|
#include "mozilla/gfx/Tools.h"
|
||||||
|
#include "mozilla/layers/LayersTypes.h"
|
||||||
#include "mozilla/Range.h"
|
#include "mozilla/Range.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
|
@ -551,6 +552,38 @@ struct BuiltDisplayList {
|
||||||
WrBuiltDisplayListDescriptor dl_desc;
|
WrBuiltDisplayListDescriptor dl_desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline WrFilterOpType ToWrFilterOpType(const layers::CSSFilterType type) {
|
||||||
|
switch (type) {
|
||||||
|
case layers::CSSFilterType::BLUR:
|
||||||
|
return WrFilterOpType::Blur;
|
||||||
|
case layers::CSSFilterType::BRIGHTNESS:
|
||||||
|
return WrFilterOpType::Brightness;
|
||||||
|
case layers::CSSFilterType::CONTRAST:
|
||||||
|
return WrFilterOpType::Contrast;
|
||||||
|
case layers::CSSFilterType::GRAYSCALE:
|
||||||
|
return WrFilterOpType::Grayscale;
|
||||||
|
case layers::CSSFilterType::HUE_ROTATE:
|
||||||
|
return WrFilterOpType::HueRotate;
|
||||||
|
case layers::CSSFilterType::INVERT:
|
||||||
|
return WrFilterOpType::Invert;
|
||||||
|
case layers::CSSFilterType::OPACITY:
|
||||||
|
return WrFilterOpType::Opacity;
|
||||||
|
case layers::CSSFilterType::SATURATE:
|
||||||
|
return WrFilterOpType::Saturate;
|
||||||
|
case layers::CSSFilterType::SEPIA:
|
||||||
|
return WrFilterOpType::Sepia;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT_UNREACHABLE("Tried to convert unknown filter type.");
|
||||||
|
return WrFilterOpType::Grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WrFilterOp ToWrFilterOp(const layers::CSSFilter& filter) {
|
||||||
|
return {
|
||||||
|
ToWrFilterOpType(filter.type),
|
||||||
|
filter.argument,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wr
|
} // namespace wr
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::{mem, slice};
|
use std::{mem, slice};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::os::raw::{c_void, c_char};
|
use std::os::raw::{c_void, c_char, c_float};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use gleam::gl;
|
use gleam::gl;
|
||||||
|
|
||||||
|
@ -59,6 +59,27 @@ type WrYuvColorSpace = YuvColorSpace;
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct WrExternalImageId(pub u64);
|
pub struct WrExternalImageId(pub 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,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct WrFilterOp {
|
||||||
|
filter_type: WrFilterOpType,
|
||||||
|
argument: c_float,
|
||||||
|
}
|
||||||
|
|
||||||
impl Into<ExternalImageId> for WrExternalImageId {
|
impl Into<ExternalImageId> for WrExternalImageId {
|
||||||
fn into(self) -> ExternalImageId {
|
fn into(self) -> ExternalImageId {
|
||||||
ExternalImageId(self.0)
|
ExternalImageId(self.0)
|
||||||
|
@ -1245,12 +1266,28 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||||
animation_id: u64,
|
animation_id: u64,
|
||||||
opacity: *const f32,
|
opacity: *const f32,
|
||||||
transform: *const WrMatrix,
|
transform: *const WrMatrix,
|
||||||
mix_blend_mode: WrMixBlendMode) {
|
mix_blend_mode: WrMixBlendMode,
|
||||||
|
filters: *const WrFilterOp,
|
||||||
|
filter_count: usize) {
|
||||||
assert!(unsafe { !is_in_render_thread() });
|
assert!(unsafe { !is_in_render_thread() });
|
||||||
|
|
||||||
let bounds = bounds.into();
|
let bounds = bounds.into();
|
||||||
|
|
||||||
let mut filters: Vec<FilterOp> = Vec::new();
|
let c_filters = make_slice(filters, filter_count);
|
||||||
|
let mut filters : Vec<FilterOp> = c_filters.iter().map(|c_filter| {
|
||||||
|
match c_filter.filter_type {
|
||||||
|
WrFilterOpType::Blur => FilterOp::Blur(Au::from_f32_px(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)),
|
||||||
|
WrFilterOpType::Saturate => FilterOp::Saturate(c_filter.argument),
|
||||||
|
WrFilterOpType::Sepia => FilterOp::Sepia(c_filter.argument),
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
let opacity = unsafe { opacity.as_ref() };
|
let opacity = unsafe { opacity.as_ref() };
|
||||||
if let Some(opacity) = opacity {
|
if let Some(opacity) = opacity {
|
||||||
if *opacity < 1.0 {
|
if *opacity < 1.0 {
|
||||||
|
|
|
@ -51,6 +51,20 @@ enum class WrExternalImageType : uint32_t {
|
||||||
Sentinel /* this must be last for serialization purposes. */
|
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,
|
||||||
|
|
||||||
|
Sentinel /* this must be last for serialization purposes. */
|
||||||
|
};
|
||||||
|
|
||||||
enum class WrGradientExtendMode : uint32_t {
|
enum class WrGradientExtendMode : uint32_t {
|
||||||
Clamp = 0,
|
Clamp = 0,
|
||||||
Repeat = 1,
|
Repeat = 1,
|
||||||
|
@ -423,6 +437,16 @@ struct WrComplexClipRegion {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WrFilterOp {
|
||||||
|
WrFilterOpType filter_type;
|
||||||
|
float argument;
|
||||||
|
|
||||||
|
bool operator==(const WrFilterOp& aOther) const {
|
||||||
|
return filter_type == aOther.filter_type &&
|
||||||
|
argument == aOther.argument;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct WrGlyphInstance {
|
struct WrGlyphInstance {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
WrPoint point;
|
WrPoint point;
|
||||||
|
@ -784,7 +808,9 @@ void wr_dp_push_stacking_context(WrState *aState,
|
||||||
uint64_t aAnimationId,
|
uint64_t aAnimationId,
|
||||||
const float *aOpacity,
|
const float *aOpacity,
|
||||||
const WrMatrix *aTransform,
|
const WrMatrix *aTransform,
|
||||||
WrMixBlendMode aMixBlendMode)
|
WrMixBlendMode aMixBlendMode,
|
||||||
|
const WrFilterOp *aFilters,
|
||||||
|
size_t aFilterCount)
|
||||||
WR_FUNC;
|
WR_FUNC;
|
||||||
|
|
||||||
WR_INLINE
|
WR_INLINE
|
||||||
|
|
|
@ -8635,6 +8635,17 @@ nsDisplayFilter::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
|
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
|
||||||
newContainerParameters, nullptr);
|
newContainerParameters, nullptr);
|
||||||
|
|
||||||
|
LayerState state = this->GetLayerState(aBuilder, aManager, newContainerParameters);
|
||||||
|
if (container && state != LAYER_SVG_EFFECTS) {
|
||||||
|
const nsTArray<nsStyleFilter>& filters = mFrame->StyleEffects()->mFilters;
|
||||||
|
nsTArray<layers::CSSFilter> cssFilters = nsTArray<layers::CSSFilter>(filters.Length());
|
||||||
|
for (const nsStyleFilter& filter : filters) {
|
||||||
|
cssFilters.AppendElement(ToCSSFilter(filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
container->SetFilterChain(Move(cssFilters));
|
||||||
|
}
|
||||||
|
|
||||||
return container.forget();
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8667,7 +8678,25 @@ nsDisplayFilter::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aParameters)
|
const ContainerLayerParameters& aParameters)
|
||||||
{
|
{
|
||||||
return LAYER_SVG_EFFECTS;
|
if (mFrame->IsFrameOfType(nsIFrame::eSVG)) {
|
||||||
|
return LAYER_SVG_EFFECTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowFilterLayers)) {
|
||||||
|
return LAYER_SVG_EFFECTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Due to differences in the way that WebRender filters operate
|
||||||
|
// only the brightness and contrast filters use that path. We
|
||||||
|
// can gradually enable more filters as WebRender bugs are fixed.
|
||||||
|
for (const nsStyleFilter& filter : mFrame->StyleEffects()->mFilters) {
|
||||||
|
if (filter.GetType() != NS_STYLE_FILTER_BRIGHTNESS &&
|
||||||
|
filter.GetType() != NS_STYLE_FILTER_CONTRAST) {
|
||||||
|
return LAYER_SVG_EFFECTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LAYER_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDisplayFilter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
bool nsDisplayFilter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
|
|
|
@ -5740,6 +5740,7 @@ pref("layers.advanced.outline-layers", 2);
|
||||||
pref("layers.advanced.solid-color", 2);
|
pref("layers.advanced.solid-color", 2);
|
||||||
pref("layers.advanced.table", 2);
|
pref("layers.advanced.table", 2);
|
||||||
pref("layers.advanced.text-layers", 2);
|
pref("layers.advanced.text-layers", 2);
|
||||||
|
pref("layers.advanced.filter-layers", 2);
|
||||||
|
|
||||||
// Whether webrender should be used as much as possible.
|
// Whether webrender should be used as much as possible.
|
||||||
pref("gfx.webrendest.enabled", false);
|
pref("gfx.webrendest.enabled", false);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче