Bug 1354946 - Add an explicit WrMatrix type for passing 4x4 matrices across the FFI boundary. r=rhunt

Right now we just cast from a float* on the C++ side to a LayoutTransform on
the Rust side, except the LayoutTransform isn't a repr(C) storage type, so
there's no guarantee that it will actually have the same layout. Adding an
explicit type and conversion code ensure that we are able to pass the matrix
across the boundary safely.

MozReview-Commit-ID: H3gK3g0K3xz
This commit is contained in:
Kartikaya Gupta 2017-04-11 08:33:58 -04:00
Родитель a4ee7fc52d
Коммит de71f88ab4
4 изменённых файлов: 36 добавлений и 4 удалений

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

@ -533,7 +533,7 @@ DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
const WrMixBlendMode& aMixBlendMode)
{
wr_dp_push_stacking_context(mWrState, aBounds, aOverflow, aMask, aOpacity,
&aTransform.components[0], aMixBlendMode);
ToWrMatrix(aTransform), aMixBlendMode);
}
void

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

@ -8,6 +8,7 @@
#include "mozilla/webrender/webrender_ffi.h"
#include "mozilla/Maybe.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/gfx/Types.h"
#include "mozilla/gfx/Tools.h"
#include "mozilla/Range.h"
@ -220,6 +221,16 @@ static inline WrSize ToWrSize(const gfx::IntSizeTyped<T>& size)
return ToWrSize(IntSizeToSize(size));
}
template<class S, class T>
static inline WrMatrix ToWrMatrix(const gfx::Matrix4x4Typed<S, T>& m)
{
WrMatrix transform;
static_assert(sizeof(m.components) == sizeof(transform.values),
"Matrix components size mismatch!");
memcpy(transform.values, m.components, sizeof(transform.values));
return transform;
}
static inline WrBorderStyle ToWrBorderStyle(const uint8_t& style)
{
switch (style) {

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

@ -204,6 +204,22 @@ impl From<LayoutRect> for WrRect {
}
}
#[repr(C)]
#[derive(Debug)]
pub struct WrMatrix {
values: [f32; 16],
}
impl WrMatrix {
pub fn to_layout_transform(&self) -> LayoutTransform {
LayoutTransform::row_major(
self.values[0], self.values[1], self.values[2], self.values[3],
self.values[4], self.values[5], self.values[6], self.values[7],
self.values[8], self.values[9], self.values[10], self.values[11],
self.values[12], self.values[13], self.values[14], self.values[15])
}
}
#[repr(C)]
pub struct WrColor {
r: f32,
@ -1083,7 +1099,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
overflow: WrRect,
mask: *const WrImageMask,
opacity: f32,
transform: &LayoutTransform,
transform: WrMatrix,
mix_blend_mode: WrMixBlendMode) {
assert!(unsafe { is_in_main_thread() });
state.z_index += 1;
@ -1114,7 +1130,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
bounds,
state.z_index,
Some(PropertyBinding::Value(*transform)),
Some(PropertyBinding::Value(transform.to_layout_transform())),
None,
mix_blend_mode,
filters);

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

@ -240,6 +240,11 @@ struct WrRect
}
};
struct WrMatrix
{
float values[16];
};
struct WrColor
{
float r;
@ -630,7 +635,7 @@ WR_FUNC;
WR_INLINE void
wr_dp_push_stacking_context(WrState *wrState, WrRect bounds,
WrRect overflow, const WrImageMask *mask,
float opacity, const float* matrix,
float opacity, WrMatrix transform,
WrMixBlendMode mixBlendMode)
WR_FUNC;