Bug 1329739 - Specify a WrMixBlendMode for WebRenderLayer r=kats

--HG--
extra : amend_source : bfa6ad8ee9cc13ab292958040ccd0f8dded15e5f
extra : histedit_source : c33cb15304d3e5806b90f04f690e000d42a5f933
This commit is contained in:
Ryan Hunt 2017-01-19 17:57:18 -06:00
parent 90ff407202
commit b66f280583
15 changed files with 146 additions and 9 deletions

View file

@ -15,6 +15,7 @@ using WrTextureFilter from "mozilla/webrender/webrender_ffi.h";
using WrLayoutSize from "mozilla/webrender/webrender_ffi.h"; using WrLayoutSize from "mozilla/webrender/webrender_ffi.h";
using WrRect from "mozilla/webrender/webrender_ffi.h"; using WrRect from "mozilla/webrender/webrender_ffi.h";
using WrGlyphArray from "mozilla/webrender/webrender_ffi.h"; using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
using WrMixBlendMode from "mozilla/webrender/webrender_ffi.h";
using MaybeImageMask from "mozilla/webrender/WebRenderTypes.h"; using MaybeImageMask from "mozilla/webrender/WebRenderTypes.h";
using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h"; using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h"; using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
@ -30,6 +31,7 @@ struct OpDPPushStackingContext {
MaybeImageMask mask; MaybeImageMask mask;
Animation[] animations; Animation[] animations;
Matrix4x4 matrix; Matrix4x4 matrix;
WrMixBlendMode mixBlendMode;
uint64_t scrollid; uint64_t scrollid;
}; };

View file

@ -9,6 +9,7 @@
#include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Rect.h"
#include "mozilla/webrender/webrender_ffi.h" #include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/layers/WebRenderBridgeChild.h" #include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
@ -39,6 +40,7 @@ WebRenderBorderLayer::RenderLayer()
Nothing(), Nothing(),
GetAnimations(), GetAnimations(),
transform, transform,
WrMixBlendMode::Normal,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand( WrBridge()->AddWebRenderCommand(

View file

@ -311,7 +311,7 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
switch (cmd.type()) { switch (cmd.type()) {
case WebRenderCommand::TOpDPPushStackingContext: { case WebRenderCommand::TOpDPPushStackingContext: {
const OpDPPushStackingContext& op = cmd.get_OpDPPushStackingContext(); const OpDPPushStackingContext& op = cmd.get_OpDPPushStackingContext();
builder.PushStackingContext(op.bounds(), op.overflow(), op.mask().ptrOr(nullptr), op.matrix()); builder.PushStackingContext(op.bounds(), op.overflow(), op.mask().ptrOr(nullptr), op.matrix(), op.mixBlendMode());
break; break;
} }
case WebRenderCommand::TOpDPPopStackingContext: { case WebRenderCommand::TOpDPPopStackingContext: {

View file

@ -76,6 +76,7 @@ WebRenderCanvasLayer::RenderLayer()
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height); gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
Maybe<WrImageMask> mask = buildMaskLayer(); Maybe<WrImageMask> mask = buildMaskLayer();
WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear; WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear;
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
WrBridge()->AddWebRenderCommand( WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds), OpDPPushStackingContext(wr::ToWrRect(relBounds),
@ -83,6 +84,7 @@ WebRenderCanvasLayer::RenderLayer()
mask, mask,
GetAnimations(), GetAnimations(),
transform, transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(LayerIntRegion(), wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, mExternalImageId)); WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(LayerIntRegion(), wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, mExternalImageId));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext()); WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());

View file

@ -7,6 +7,7 @@
#include "LayersLogging.h" #include "LayersLogging.h"
#include "mozilla/webrender/webrender_ffi.h" #include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/WebRenderBridgeChild.h" #include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla { namespace mozilla {
@ -32,6 +33,7 @@ WebRenderColorLayer::RenderLayer()
gfx::Matrix4x4 transform;// = GetTransform(); gfx::Matrix4x4 transform;// = GetTransform();
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent(); gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height); gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
Maybe<WrImageMask> mask = buildMaskLayer(); Maybe<WrImageMask> mask = buildMaskLayer();
@ -41,6 +43,7 @@ WebRenderColorLayer::RenderLayer()
mask, mask,
GetAnimations(), GetAnimations(),
transform, transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand( WrBridge()->AddWebRenderCommand(
OpDPPushRect(wr::ToWrRect(rect), wr::ToWrRect(clip), mColor.r, mColor.g, mColor.b, mColor.a)); OpDPPushRect(wr::ToWrRect(rect), wr::ToWrRect(clip), mColor.r, mColor.g, mColor.b, mColor.a));

View file

@ -7,6 +7,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "mozilla/layers/WebRenderBridgeChild.h" #include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "LayersLogging.h" #include "LayersLogging.h"
namespace mozilla { namespace mozilla {
@ -23,6 +24,8 @@ WebRenderContainerLayer::RenderLayer()
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height); gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
gfx::Matrix4x4 transform;// = GetTransform(); gfx::Matrix4x4 transform;// = GetTransform();
if (gfxPrefs::LayersDump()) printf_stderr("ContainerLayer %p using %s as bounds, %s as overflow, %s as transform\n", this, Stringify(relBounds).c_str(), Stringify(overflow).c_str(), Stringify(transform).c_str()); if (gfxPrefs::LayersDump()) printf_stderr("ContainerLayer %p using %s as bounds, %s as overflow, %s as transform\n", this, Stringify(relBounds).c_str(), Stringify(overflow).c_str(), Stringify(transform).c_str());
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
Maybe<WrImageMask> mask = buildMaskLayer(); Maybe<WrImageMask> mask = buildMaskLayer();
@ -32,6 +35,7 @@ WebRenderContainerLayer::RenderLayer()
mask, mask,
GetLayer()->GetAnimations(), GetLayer()->GetAnimations(),
transform, transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
for (LayerPolygon& child : children) { for (LayerPolygon& child : children) {
if (child.layer->IsBackfaceHidden()) { if (child.layer->IsBackfaceHidden()) {

View file

@ -144,6 +144,7 @@ WebRenderImageLayer::RenderLayer()
Matrix4x4 transform;// = GetTransform(); Matrix4x4 transform;// = GetTransform();
Maybe<WrImageMask> mask = buildMaskLayer(); Maybe<WrImageMask> mask = buildMaskLayer();
WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear; WrTextureFilter filter = (mSamplingFilter == gfx::SamplingFilter::POINT) ? WrTextureFilter::Point : WrTextureFilter::Linear;
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
WrBridge()->AddWebRenderCommand( WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds), OpDPPushStackingContext(wr::ToWrRect(relBounds),
@ -151,6 +152,7 @@ WebRenderImageLayer::RenderLayer()
mask, mask,
GetAnimations(), GetAnimations(),
transform, transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(LayerIntRegion(), wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, mExternalImageId)); WrBridge()->AddWebRenderCommand(OpDPPushExternalImageId(LayerIntRegion(), wr::ToWrRect(rect), wr::ToWrRect(clip), Nothing(), filter, mExternalImageId));
WrBridge()->AddWebRenderCommand(OpDPPopStackingContext()); WrBridge()->AddWebRenderCommand(OpDPPopStackingContext());

View file

@ -163,6 +163,7 @@ WrScrollFrameStackingContextGenerator::WrScrollFrameStackingContextGenerator(
Nothing(), Nothing(),
layer->GetAnimations(), layer->GetAnimations(),
identity, identity,
WrMixBlendMode::Normal,
fm.GetScrollId())); fm.GetScrollId()));
} }
} }

View file

@ -272,6 +272,15 @@ struct ParamTraits<WrTextureFilter>
{ {
}; };
template<>
struct ParamTraits<WrMixBlendMode>
: public ContiguousEnumSerializer<
WrMixBlendMode,
WrMixBlendMode::Normal,
WrMixBlendMode::Sentinel>
{
};
} // namespace IPC } // namespace IPC
#endif // GFX_WEBRENDERMESSAGEUTILS_H #endif // GFX_WEBRENDERMESSAGEUTILS_H

View file

@ -143,6 +143,7 @@ WebRenderPaintedLayer::RenderLayer()
Rect relBounds = TransformedVisibleBoundsRelativeToParent(); Rect relBounds = TransformedVisibleBoundsRelativeToParent();
Rect overflow(0, 0, relBounds.width, relBounds.height); Rect overflow(0, 0, relBounds.width, relBounds.height);
Matrix4x4 transform;// = GetTransform(); Matrix4x4 transform;// = GetTransform();
WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
WrBridge()->AddWebRenderCommand( WrBridge()->AddWebRenderCommand(
OpDPPushStackingContext(wr::ToWrRect(relBounds), OpDPPushStackingContext(wr::ToWrRect(relBounds),
@ -150,6 +151,7 @@ WebRenderPaintedLayer::RenderLayer()
mask, mask,
GetAnimations(), GetAnimations(),
transform, transform,
mixBlendMode,
FrameMetrics::NULL_SCROLL_ID)); FrameMetrics::NULL_SCROLL_ID));
ContentClientRemoteBuffer* contentClientRemote = static_cast<ContentClientRemoteBuffer*>(mContentClient.get()); ContentClientRemoteBuffer* contentClientRemote = static_cast<ContentClientRemoteBuffer*>(mContentClient.get());

View file

@ -300,10 +300,11 @@ void
DisplayListBuilder::PushStackingContext(const WrRect& aBounds, DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
const WrRect& aOverflow, const WrRect& aOverflow,
const WrImageMask* aMask, const WrImageMask* aMask,
const gfx::Matrix4x4& aTransform) const gfx::Matrix4x4& aTransform,
const WrMixBlendMode& aMixBlendMode)
{ {
wr_dp_push_stacking_context(mWrState, aBounds, aOverflow, aMask, wr_dp_push_stacking_context(mWrState, aBounds, aOverflow, aMask,
&aTransform.components[0]); &aTransform.components[0], aMixBlendMode);
} }
void void

View file

@ -108,7 +108,8 @@ public:
void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const WrRect& aOverflow, const WrRect& aOverflow,
const WrImageMask* aMask, // TODO: needs a wrapper. const WrImageMask* aMask, // TODO: needs a wrapper.
const gfx::Matrix4x4& aTransform); const gfx::Matrix4x4& aTransform,
const WrMixBlendMode& aMixBlendMode);
void PopStackingContext(); void PopStackingContext();

View file

@ -8,6 +8,7 @@
#include "mozilla/webrender/webrender_ffi.h" #include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/gfx/Types.h"
// The infrastructure and plumbing to use the render thread is not entirely in // The infrastructure and plumbing to use the render thread is not entirely in
// place yet. In order to land code and work in parallel we have to maintain // place yet. In order to land code and work in parallel we have to maintain
@ -28,6 +29,45 @@ typedef mozilla::Maybe<WrImageMask> MaybeImageMask;
namespace mozilla { namespace mozilla {
namespace wr { namespace wr {
static inline WrMixBlendMode ToWrMixBlendMode(gfx::CompositionOp compositionOp)
{
switch (compositionOp)
{
case gfx::CompositionOp::OP_MULTIPLY:
return WrMixBlendMode::Multiply;
case gfx::CompositionOp::OP_SCREEN:
return WrMixBlendMode::Screen;
case gfx::CompositionOp::OP_OVERLAY:
return WrMixBlendMode::Overlay;
case gfx::CompositionOp::OP_DARKEN:
return WrMixBlendMode::Darken;
case gfx::CompositionOp::OP_LIGHTEN:
return WrMixBlendMode::Lighten;
case gfx::CompositionOp::OP_COLOR_DODGE:
return WrMixBlendMode::ColorDodge;
case gfx::CompositionOp::OP_COLOR_BURN:
return WrMixBlendMode::ColorBurn;
case gfx::CompositionOp::OP_HARD_LIGHT:
return WrMixBlendMode::HardLight;
case gfx::CompositionOp::OP_SOFT_LIGHT:
return WrMixBlendMode::SoftLight;
case gfx::CompositionOp::OP_DIFFERENCE:
return WrMixBlendMode::Difference;
case gfx::CompositionOp::OP_EXCLUSION:
return WrMixBlendMode::Exclusion;
case gfx::CompositionOp::OP_HUE:
return WrMixBlendMode::Hue;
case gfx::CompositionOp::OP_SATURATION:
return WrMixBlendMode::Saturation;
case gfx::CompositionOp::OP_COLOR:
return WrMixBlendMode::Color;
case gfx::CompositionOp::OP_LUMINOSITY:
return WrMixBlendMode::Luminosity;
default:
return WrMixBlendMode::Normal;
}
}
static inline WrColor ToWrColor(const gfx::Color& color) static inline WrColor ToWrColor(const gfx::Color& color)
{ {
WrColor c; WrColor c;

View file

@ -8,7 +8,7 @@ use gleam::gl;
use webrender_traits::{BorderSide, BorderStyle, BorderRadius}; use webrender_traits::{BorderSide, BorderStyle, BorderRadius};
use webrender_traits::{PipelineId, ClipRegion}; use webrender_traits::{PipelineId, ClipRegion};
use webrender_traits::{Epoch, ColorF, GlyphInstance}; use webrender_traits::{Epoch, ColorF, GlyphInstance};
use webrender_traits::{ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, RendererKind}; use webrender_traits::{ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, RendererKind, MixBlendMode};
use webrender_traits::{ExternalImageId, RenderApi, FontKey}; use webrender_traits::{ExternalImageId, RenderApi, FontKey};
use webrender_traits::{DeviceUintSize, ExternalEvent}; use webrender_traits::{DeviceUintSize, ExternalEvent};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform}; use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform};
@ -401,6 +401,53 @@ impl ExternalImageHandler for WrExternalImageHandler {
} }
} }
#[repr(C)]
pub enum WrMixBlendMode
{
Normal,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
}
impl WrMixBlendMode
{
pub fn to_mix_blend_mode(self) -> MixBlendMode
{
match self
{
WrMixBlendMode::Normal => MixBlendMode::Normal,
WrMixBlendMode::Multiply => MixBlendMode::Multiply,
WrMixBlendMode::Screen => MixBlendMode::Screen,
WrMixBlendMode::Overlay => MixBlendMode::Overlay,
WrMixBlendMode::Darken => MixBlendMode::Darken,
WrMixBlendMode::Lighten => MixBlendMode::Lighten,
WrMixBlendMode::ColorDodge => MixBlendMode::ColorDodge,
WrMixBlendMode::ColorBurn => MixBlendMode::ColorBurn,
WrMixBlendMode::HardLight => MixBlendMode::HardLight,
WrMixBlendMode::SoftLight => MixBlendMode::SoftLight,
WrMixBlendMode::Difference => MixBlendMode::Difference,
WrMixBlendMode::Exclusion => MixBlendMode::Exclusion,
WrMixBlendMode::Hue => MixBlendMode::Hue,
WrMixBlendMode::Saturation => MixBlendMode::Saturation,
WrMixBlendMode::Color => MixBlendMode::Color,
WrMixBlendMode::Luminosity => MixBlendMode::Luminosity,
}
}
}
// TODO: Remove. // TODO: Remove.
#[no_mangle] #[no_mangle]
pub extern fn wr_init_window(root_pipeline_id: u64, pub extern fn wr_init_window(root_pipeline_id: u64,
@ -489,14 +536,14 @@ pub extern fn wr_window_dp_begin(window: &mut WrWindowState, state: &mut WrState
} }
#[no_mangle] #[no_mangle]
pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, overflow: WrRect, mask: *const WrImageMask, transform: &LayoutTransform) pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, overflow: WrRect, mask: *const WrImageMask, transform: &LayoutTransform, mix_blend_mode: WrMixBlendMode)
{ {
assert!( unsafe { is_in_compositor_thread() }); assert!( unsafe { is_in_compositor_thread() });
state.z_index += 1; state.z_index += 1;
let bounds = bounds.to_rect(); let bounds = bounds.to_rect();
let overflow = overflow.to_rect(); let overflow = overflow.to_rect();
let mix_blend_mode = mix_blend_mode.to_mix_blend_mode();
// convert from the C type to the Rust type // convert from the C type to the Rust type
let mask = unsafe { mask.as_ref().map(|&WrImageMask{image, ref rect,repeat}| ImageMask{image: image, rect: rect.to_rect(), repeat: repeat}) }; let mask = unsafe { mask.as_ref().map(|&WrImageMask{image, ref rect,repeat}| ImageMask{image: image, rect: rect.to_rect(), repeat: repeat}) };
@ -508,7 +555,7 @@ pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, ov
state.z_index, state.z_index,
transform, transform,
&LayoutTransform::identity(), &LayoutTransform::identity(),
webrender_traits::MixBlendMode::Normal, mix_blend_mode,
Vec::new()); Vec::new());
} }

View file

@ -178,6 +178,27 @@ struct WrExternalImageIdHandler {
ReleaseExternalImageCallback release_func; ReleaseExternalImageCallback release_func;
}; };
enum class WrMixBlendMode
{
Normal,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
Sentinel,
};
struct WrWindowState; struct WrWindowState;
#ifdef MOZ_ENABLE_WEBRENDER #ifdef MOZ_ENABLE_WEBRENDER
@ -303,7 +324,7 @@ WR_FUNC;
WR_INLINE void WR_INLINE void
wr_dp_push_stacking_context(WrState *wrState, WrRect bounds, wr_dp_push_stacking_context(WrState *wrState, WrRect bounds,
WrRect overflow, const WrImageMask *mask, WrRect overflow, const WrImageMask *mask,
const float* matrix) const float* matrix, WrMixBlendMode mixBlendMode)
WR_FUNC; WR_FUNC;
//XXX: matrix should use a proper type //XXX: matrix should use a proper type