Bug 1340338 - Add WebRender bindings for linear and radial gradients r=nical

--HG--
extra : rebase_source : 322347fb1a55432ef5a85196a5c4f7e847c4fe7b
extra : histedit_source : 2173a02c440fd949469f06039e4ad3ee720dca43
This commit is contained in:
Ryan Hunt 2017-02-16 19:51:32 -05:00
Родитель 7eb79c28fe
Коммит 9e2d6c82f4
8 изменённых файлов: 242 добавлений и 1 удалений

Просмотреть файл

@ -15,6 +15,8 @@ using WrColor from "mozilla/webrender/webrender_ffi.h";
using WrLayoutSize from "mozilla/webrender/webrender_ffi.h";
using WrRect from "mozilla/webrender/webrender_ffi.h";
using WrPoint from "mozilla/webrender/webrender_ffi.h";
using WrGradientStop from "mozilla/webrender/webrender_ffi.h";
using WrGradientExtendMode from "mozilla/webrender/webrender_ffi.h";
using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
using WrMixBlendMode from "mozilla/webrender/webrender_ffi.h";
using WrBoxShadowClipMode from "mozilla/webrender/webrender_ffi.h";
@ -67,6 +69,26 @@ struct OpDPPushBorder {
WrBorderRadius radius;
};
struct OpDPPushLinearGradient {
WrRect bounds;
WrRect clip;
WrPoint startPoint;
WrPoint endPoint;
WrGradientExtendMode extendMode;
WrGradientStop[] stops;
};
struct OpDPPushRadialGradient {
WrRect bounds;
WrRect clip;
WrPoint startCenter;
WrPoint endCenter;
float startRadius;
float endRadius;
WrGradientExtendMode extendMode;
WrGradientStop[] stops;
};
struct OpDPPushImage {
WrRect bounds;
WrRect clip;
@ -119,6 +141,8 @@ union WebRenderCommand {
OpDPPopScrollLayer;
OpDPPushRect;
OpDPPushBorder;
OpDPPushLinearGradient;
OpDPPushRadialGradient;
OpDPPushImage;
OpDPPushExternalImageId;
OpDPPushIframe;

Просмотреть файл

@ -286,6 +286,21 @@ WebRenderBridgeParent::ProcessWebrenderCommands(InfallibleTArray<WebRenderComman
op.radius());
break;
}
case WebRenderCommand::TOpDPPushLinearGradient: {
const OpDPPushLinearGradient& op = cmd.get_OpDPPushLinearGradient();
builder.PushLinearGradient(op.bounds(), op.clip(),
op.startPoint(), op.endPoint(),
op.stops(), op.extendMode());
break;
}
case WebRenderCommand::TOpDPPushRadialGradient: {
const OpDPPushRadialGradient& op = cmd.get_OpDPPushRadialGradient();
builder.PushRadialGradient(op.bounds(), op.clip(),
op.startCenter(), op.endCenter(),
op.startRadius(), op.endRadius(),
op.stops(), op.extendMode());
break;
}
case WebRenderCommand::TOpDPPushImage: {
const OpDPPushImage& op = cmd.get_OpDPPushImage();
builder.PushImage(op.bounds(), op.clip(),

Просмотреть файл

@ -189,6 +189,24 @@ struct ParamTraits<WrGlyphArray>
}
};
template<>
struct ParamTraits<WrGradientStop>
{
static void
Write(Message* aMsg, const WrGradientStop& aParam)
{
WriteParam(aMsg, aParam.offset);
WriteParam(aMsg, aParam.color);
}
static bool
Read(const Message* aMsg, PickleIterator* aIter, WrGradientStop* aResult)
{
return ReadParam(aMsg, aIter, &aResult->offset)
&& ReadParam(aMsg, aIter, &aResult->color);
}
};
template<>
struct ParamTraits<WrBorderSide>
{
@ -336,6 +354,15 @@ struct ParamTraits<WrBoxShadowClipMode>
{
};
template<>
struct ParamTraits<WrGradientExtendMode>
: public ContiguousEnumSerializer<
WrGradientExtendMode,
WrGradientExtendMode::Clamp,
WrGradientExtendMode::Sentinel>
{
};
} // namespace IPC
#endif // GFX_WEBRENDERMESSAGEUTILS_H

Просмотреть файл

@ -357,6 +357,39 @@ DisplayListBuilder::PushRect(const WrRect& aBounds,
wr_dp_push_rect(mWrState, aBounds, aClip, aColor);
}
void
DisplayListBuilder::PushLinearGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrPoint& aStartPoint,
const WrPoint& aEndPoint,
const nsTArray<WrGradientStop>& aStops,
wr::GradientExtendMode aExtendMode)
{
wr_dp_push_linear_gradient(mWrState,
aBounds, aClip,
aStartPoint, aEndPoint,
aStops.Elements(), aStops.Length(),
aExtendMode);
}
void
DisplayListBuilder::PushRadialGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrPoint& aStartCenter,
const WrPoint& aEndCenter,
float aStartRadius,
float aEndRadius,
const nsTArray<WrGradientStop>& aStops,
wr::GradientExtendMode aExtendMode)
{
wr_dp_push_radial_gradient(mWrState,
aBounds, aClip,
aStartCenter, aEndCenter,
aStartRadius, aEndRadius,
aStops.Elements(), aStops.Length(),
aExtendMode);
}
void
DisplayListBuilder::PushImage(const WrRect& aBounds,
const WrRect& aClip,

Просмотреть файл

@ -122,6 +122,22 @@ public:
const WrRect& aClip,
const WrColor& aColor);
void PushLinearGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrPoint& aStartPoint,
const WrPoint& aEndPoint,
const nsTArray<WrGradientStop>& aStops,
wr::GradientExtendMode aExtendMode);
void PushRadialGradient(const WrRect& aBounds,
const WrRect& aClip,
const WrPoint& aStartCenter,
const WrPoint& aEndCenter,
float aStartRadius,
float aEndRadius,
const nsTArray<WrGradientStop>& aStops,
wr::GradientExtendMode aExtendMode);
void PushImage(const WrRect& aBounds,
const WrRect& aClip,
const WrImageMask* aMask,

Просмотреть файл

@ -16,6 +16,7 @@ typedef mozilla::Maybe<WrImageMask> MaybeImageMask;
namespace mozilla {
namespace wr {
typedef WrGradientExtendMode GradientExtendMode;
typedef WrMixBlendMode MixBlendMode;
typedef WrImageRendering ImageRendering;
typedef WrImageFormat ImageFormat;
@ -182,6 +183,14 @@ static inline WrBorderSide ToWrBorderSide(const LayerCoord width, const gfx::Col
return bs;
}
static inline WrPoint ToWrPoint(const LayerPoint point)
{
WrPoint lp;
lp.x = point.x;
lp.y = point.y;
return lp;
}
static inline WrLayoutSize ToWrLayoutSize(const LayerSize size)
{
WrLayoutSize ls;

Просмотреть файл

@ -5,7 +5,7 @@ use std::os::raw::{c_void, c_char};
use gleam::gl;
use webrender_traits::{BorderSide, BorderStyle, BorderRadius};
use webrender_traits::{PipelineId, ClipRegion, PropertyBinding};
use webrender_traits::{Epoch, ColorF, GlyphInstance, ImageDescriptor};
use webrender_traits::{Epoch, ExtendMode, ColorF, GlyphInstance, GradientStop, ImageDescriptor};
use webrender_traits::{FilterOp, ImageData, ImageFormat, ImageKey, ImageMask, ImageRendering, RendererKind, MixBlendMode};
use webrender_traits::{ExternalImageId, RenderApi, FontKey};
use webrender_traits::{DeviceUintSize, ExternalEvent};
@ -517,6 +517,25 @@ impl WrMixBlendMode
}
}
#[repr(C)]
pub enum WrGradientExtendMode
{
Clamp,
Repeat,
}
impl WrGradientExtendMode
{
pub fn to_gradient_extend_mode(self) -> ExtendMode
{
match self
{
WrGradientExtendMode::Clamp => ExtendMode::Clamp,
WrGradientExtendMode::Repeat => ExtendMode::Repeat,
}
}
}
#[no_mangle]
pub extern fn wr_dp_push_stacking_context(state:&mut WrState, bounds: WrRect, overflow: WrRect, mask: *const WrImageMask, opacity: f32, transform: &LayoutTransform, mix_blend_mode: WrMixBlendMode)
{
@ -681,6 +700,49 @@ pub extern fn wr_dp_push_border(state: &mut WrState, rect: WrRect, clip: WrRect,
radius.to_border_radius());
}
#[no_mangle]
pub extern fn wr_dp_push_linear_gradient(state: &mut WrState, rect: WrRect, clip: WrRect,
start_point: WrPoint, end_point: WrPoint,
stops: * const WrGradientStop, stops_count: usize,
extend_mode: WrGradientExtendMode) {
assert!( unsafe { is_in_compositor_thread() });
let stops = WrGradientStop::to_gradient_stops(unsafe { slice::from_raw_parts(stops, stops_count) });
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
state.frame_builder.dl_builder.push_gradient(
rect.to_rect(),
clip_region,
start_point.to_point(),
end_point.to_point(),
stops,
extend_mode.to_gradient_extend_mode()
);
}
#[no_mangle]
pub extern fn wr_dp_push_radial_gradient(state: &mut WrState, rect: WrRect, clip: WrRect,
start_center: WrPoint, end_center: WrPoint,
start_radius: f32, end_radius: f32,
stops: * const WrGradientStop, stops_count: usize,
extend_mode: WrGradientExtendMode) {
assert!( unsafe { is_in_compositor_thread() });
let stops = WrGradientStop::to_gradient_stops(unsafe { slice::from_raw_parts(stops, stops_count) });
let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
state.frame_builder.dl_builder.push_radial_gradient(
rect.to_rect(),
clip_region,
start_center.to_point(),
start_radius,
end_center.to_point(),
end_radius,
stops,
extend_mode.to_gradient_extend_mode()
);
}
#[no_mangle]
pub extern fn wr_dp_push_iframe(state: &mut WrState, rect: WrRect, clip: WrRect, pipeline_id: PipelineId) {
assert!( unsafe { is_in_compositor_thread() });
@ -745,6 +807,28 @@ impl WrBorderSide
}
}
#[repr(C)]
pub struct WrGradientStop
{
offset: f32,
color: WrColor,
}
impl WrGradientStop
{
pub fn to_gradient_stop(&self) -> GradientStop
{
GradientStop {
offset: self.offset,
color: self.color.to_color(),
}
}
pub fn to_gradient_stops(stops: &[WrGradientStop]) -> Vec<GradientStop>
{
stops.iter().map(|x| x.to_gradient_stop()).collect()
}
}
#[repr(C)]
pub struct WrLayoutSize
{

Просмотреть файл

@ -142,6 +142,14 @@ enum class WrMixBlendMode: uint32_t
Sentinel /* this must be last, for IPC serialization purposes */
};
enum class WrGradientExtendMode : uint32_t
{
Clamp = 0,
Repeat = 1,
Sentinel /* this must be last, for IPC serialization purposes */
};
// -----
// Typedefs for struct fields and function signatures below.
// -----
@ -206,6 +214,16 @@ struct WrGlyphArray
}
};
struct WrGradientStop {
float offset;
WrColor color;
bool operator==(const WrGradientStop& aRhs) const
{
return offset == aRhs.offset && color == aRhs.color;
}
};
struct WrBorderSide {
float width;
WrColor color;
@ -489,6 +507,21 @@ wr_dp_push_border(WrState* wrState, WrRect bounds, WrRect clip,
WrBorderRadius radius)
WR_FUNC;
WR_INLINE void
wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrRect clip,
WrPoint startPoint, WrPoint endPoint,
const WrGradientStop* stops, size_t stopsCount,
WrGradientExtendMode extendMode);
WR_FUNC;
WR_INLINE void
wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrRect clip,
WrPoint startCenter, WrPoint endCenter,
float startRadius, float endRadius,
const WrGradientStop* stops, size_t stopsCount,
WrGradientExtendMode extendMode);
WR_FUNC;
WR_INLINE void
wr_dp_push_image(WrState* wrState, WrRect bounds, WrRect clip,
const WrImageMask* mask, WrImageRendering filter, WrImageKey key)