Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync changes from mozilla-central gfx/wr #3841

Merged
merged 7 commits into from Jan 23, 2020

Bug 1606771 - Fix the middle area of border-image nine-patches. r=gw

Unlike the border areas that only nead their own dimensions, the middle area of a border-image determines its repetition parameter based on the size of the borders. A new flag is provided for the brush_image shader to know whether to use the segment's own rect or look at the borders when computing the pattern's size.

Differential Revision: https://phabricator.services.mozilla.com/D59675

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/834d49acd3c02a7e5ae75d0a4d01a55e69c8fdba
  • Loading branch information
nical authored and moz-gfx committed Jan 23, 2020
commit 8f77d131d0fd58bdf6a1ce8b00570d8c5ed25095
@@ -114,7 +114,8 @@ void multi_brush_vs(
#define BRUSH_FLAG_SEGMENT_REPEAT_Y 8
#define BRUSH_FLAG_SEGMENT_REPEAT_X_ROUND 16
#define BRUSH_FLAG_SEGMENT_REPEAT_Y_ROUND 32
#define BRUSH_FLAG_TEXEL_RECT 64
#define BRUSH_FLAG_SEGMENT_NINEPATCH_MIDDLE 64
#define BRUSH_FLAG_TEXEL_RECT 128

#define INVALID_SEGMENT_INDEX 0xffff

@@ -104,13 +104,39 @@ void image_brush_vs(
uv1 = res.uv_rect.p0 + segment_data.zw * uv_size;

#ifdef WR_FEATURE_REPETITION
// The repetition parameters for the middle area of a nine-patch are based
// on the size of the border segments rather than the middle segment itself,
// taking top and left by default, falling back to bottom and right when a
// size is empty.
// TODO(bug 1609893): Move this logic of the CPU as well as other sources of
// branchiness in this shader.
if ((brush_flags & BRUSH_FLAG_SEGMENT_NINEPATCH_MIDDLE) != 0) {
dx = segment_data.x;
dy = segment_data.y;
stretch_size.x = segment_rect.p0.x - prim_rect.p0.x;
stretch_size.y = segment_rect.p0.y - prim_rect.p0.y;
float epsilon = 0.001;
if (dx < epsilon || stretch_size.x < epsilon) {
dx = 1.0 - segment_data.z;
stretch_size.x = prim_rect.p0.x + prim_rect.size.x
- segment_rect.p0.x - segment_rect.size.x;
}
if (dy < epsilon || stretch_size.y < epsilon) {
dy = 1.0 - segment_data.w;
stretch_size.y = prim_rect.p0.y + prim_rect.size.y
- segment_rect.p0.y - segment_rect.size.y;
}
}

vec2 original_stretch_size = stretch_size;
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) {
stretch_size.x = local_rect.size.y / dy * dx;
stretch_size.x = original_stretch_size.y / dy * dx;
}
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_Y) != 0) {
stretch_size.y = local_rect.size.x / dx * dy;
stretch_size.y = original_stretch_size.x / dx * dy;
}
#endif

} else {
#ifdef WR_FEATURE_REPETITION
if ((brush_flags & BRUSH_FLAG_SEGMENT_REPEAT_X) != 0) {
@@ -1349,7 +1349,8 @@ impl NinePatchDescriptor {
rect: LayoutRect,
uv_rect: TexelRect,
repeat_horizontal: RepeatMode,
repeat_vertical: RepeatMode
repeat_vertical: RepeatMode,
extra_flags: BrushFlags,
) {
if uv_rect.uv1.x < uv_rect.uv0.x || uv_rect.uv1.y < uv_rect.uv0.y {
return;
@@ -1359,7 +1360,8 @@ impl NinePatchDescriptor {
// instances in this primitive.
let mut brush_flags =
BrushFlags::SEGMENT_RELATIVE |
BrushFlags::SEGMENT_TEXEL_RECT;
BrushFlags::SEGMENT_TEXEL_RECT |
extra_flags;

// Enable repeat modes on the segment.
if repeat_horizontal == RepeatMode::Repeat {
@@ -1399,31 +1401,35 @@ impl NinePatchDescriptor {
LayoutRect::from_floats(tl_outer.x, tl_outer.y, tl_inner.x, tl_inner.y),
TexelRect::new(px0, py0, px1, py1),
RepeatMode::Stretch,
RepeatMode::Stretch
RepeatMode::Stretch,
BrushFlags::empty(),
);
// Top right
add_segment(
&mut segments,
LayoutRect::from_floats(tr_inner.x, tr_outer.y, tr_outer.x, tr_inner.y),
TexelRect::new(px2, py0, px3, py1),
RepeatMode::Stretch,
RepeatMode::Stretch
RepeatMode::Stretch,
BrushFlags::empty(),
);
// Bottom right
add_segment(
&mut segments,
LayoutRect::from_floats(br_inner.x, br_inner.y, br_outer.x, br_outer.y),
TexelRect::new(px2, py2, px3, py3),
RepeatMode::Stretch,
RepeatMode::Stretch
RepeatMode::Stretch,
BrushFlags::empty(),
);
// Bottom left
add_segment(
&mut segments,
LayoutRect::from_floats(bl_outer.x, bl_inner.y, bl_inner.x, bl_outer.y),
TexelRect::new(px0, py2, px1, py3),
RepeatMode::Stretch,
RepeatMode::Stretch
RepeatMode::Stretch,
BrushFlags::empty(),
);

// Center
@@ -1433,7 +1439,8 @@ impl NinePatchDescriptor {
LayoutRect::from_floats(tl_inner.x, tl_inner.y, tr_inner.x, bl_inner.y),
TexelRect::new(px1, py1, px2, py2),
self.repeat_horizontal,
self.repeat_vertical
self.repeat_vertical,
BrushFlags::SEGMENT_NINEPATCH_MIDDLE,
);
}

@@ -1446,6 +1453,7 @@ impl NinePatchDescriptor {
TexelRect::new(px1, py0, px2, py1),
self.repeat_horizontal,
RepeatMode::Stretch,
BrushFlags::empty(),
);
// Bottom
add_segment(
@@ -1454,6 +1462,7 @@ impl NinePatchDescriptor {
TexelRect::new(px1, py2, px2, py3),
self.repeat_horizontal,
RepeatMode::Stretch,
BrushFlags::empty(),
);
// Left
add_segment(
@@ -1462,6 +1471,7 @@ impl NinePatchDescriptor {
TexelRect::new(px0, py1, px1, py2),
RepeatMode::Stretch,
self.repeat_vertical,
BrushFlags::empty(),
);
// Right
add_segment(
@@ -1470,6 +1480,7 @@ impl NinePatchDescriptor {
TexelRect::new(px2, py1, px3, py2),
RepeatMode::Stretch,
self.repeat_vertical,
BrushFlags::empty(),
);

segments
@@ -411,12 +411,14 @@ bitflags! {
const SEGMENT_REPEAT_X = 4;
/// Repeat UVs vertically.
const SEGMENT_REPEAT_Y = 8;
/// Horizontally follow border-image-repeat: round
/// Horizontally follow border-image-repeat: round.
const SEGMENT_REPEAT_X_ROUND = 16;
/// Vorizontally follow border-image-repeat: round
/// Vertically follow border-image-repeat: round.
const SEGMENT_REPEAT_Y_ROUND = 32;
/// Middle (fill) area of a border-image-repeat.
const SEGMENT_NINEPATCH_MIDDLE = 64;
/// The extra segment data is a texel rect.
const SEGMENT_TEXEL_RECT = 64;
const SEGMENT_TEXEL_RECT = 128;
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.