mirror of
https://github.com/zen-browser/desktop.git
synced 2026-09-09 23:05:33 +00:00
gh-6302: Remove corner shape for browser stack rendering (gh-15318)
This commit is contained in:
@@ -20,6 +20,9 @@
|
||||
- name: zen.theme.acrylic-elements
|
||||
value: "@IS_TWILIGHT@"
|
||||
|
||||
- name: zen.theme.squircle-browser-view
|
||||
value: "@IS_TWILIGHT@"
|
||||
|
||||
- name: zen.theme.disable-lightweight
|
||||
value: true
|
||||
|
||||
|
||||
1089
src/external-patches/firefox/bug_2047627_corner_shape_borders.patch
Normal file
1089
src/external-patches/firefox/bug_2047627_corner_shape_borders.patch
Normal file
File diff suppressed because it is too large
Load Diff
558
src/external-patches/firefox/bug_2063169/D319577.patch
Normal file
558
src/external-patches/firefox/bug_2063169/D319577.patch
Normal file
@@ -0,0 +1,558 @@
|
||||
diff --git a/gfx/wr/webrender/res/ps_quad_mask.glsl b/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
--- a/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
+++ b/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
@@ -19,12 +19,14 @@
|
||||
// We pack 4 vec3 clip planes into 3 vec4 to save a varying slot.
|
||||
flat varying highp vec4 vClipPlane_A;
|
||||
flat varying highp vec4 vClipPlane_B;
|
||||
flat varying highp vec4 vClipPlane_C;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
flat varying highp vec4 vClipShape;
|
||||
flat varying highp vec4 vClipClampedInset;
|
||||
+#endif
|
||||
|
||||
#endif
|
||||
flat varying highp vec2 vClipMode;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
@@ -40,12 +42,14 @@
|
||||
vec4 radii;
|
||||
#else
|
||||
vec4 radii_top;
|
||||
vec4 radii_bottom;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vec4 shape;
|
||||
vec4 inset;
|
||||
+#endif
|
||||
#endif
|
||||
float mode;
|
||||
int space;
|
||||
};
|
||||
|
||||
@@ -58,22 +62,29 @@
|
||||
vec4 texels[3] = fetch_from_gpu_buffer_3f(index);
|
||||
clip.rect = RectWithEndpoint(texels[0].xy, texels[0].zw);
|
||||
clip.radii = texels[1];
|
||||
clip.mode = texels[2].x;
|
||||
#else
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vec4 texels[6] = fetch_from_gpu_buffer_6f(index);
|
||||
+#else
|
||||
+ vec4 texels[4] = fetch_from_gpu_buffer_4f(index);
|
||||
+#endif
|
||||
clip.rect = RectWithEndpoint(texels[0].xy, texels[0].zw);
|
||||
clip.radii_top = texels[1];
|
||||
clip.radii_bottom = texels[2];
|
||||
clip.mode = texels[3].x;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
clip.shape = texels[4];
|
||||
clip.inset = texels[5];
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vec4 precalc_corner(vec2 center, vec2 radii, vec2 inset, vec2 clip_sign, float k) {
|
||||
if (k == 1.0) {
|
||||
// round/ellipse corner, precalc the ellipse parameters
|
||||
return vec4(center, inverse_radii_squared(radii));
|
||||
} else {
|
||||
@@ -85,10 +96,11 @@
|
||||
radii = offset_radii.zw;
|
||||
}
|
||||
return vec4(center, inverse_radii(radii));
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
void pattern_vertex(PrimitiveInfo prim_info) {
|
||||
|
||||
Clip clip = fetch_clip(aClipData.y);
|
||||
Transform clip_transform = fetch_transform(aClipData.x);
|
||||
@@ -121,10 +133,11 @@
|
||||
vec2 r_tl = clip.radii_top.xy;
|
||||
vec2 r_tr = clip.radii_top.zw;
|
||||
vec2 r_br = clip.radii_bottom.zw;
|
||||
vec2 r_bl = clip.radii_bottom.xy;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipCenter_Radius_TL = precalc_corner(clip.rect.p0 + r_tl,
|
||||
r_tl,
|
||||
clip.inset.wx,
|
||||
vec2(-1.0, -1.0),
|
||||
clip.shape.x);
|
||||
@@ -146,10 +159,25 @@
|
||||
clip.rect.p1.y - r_bl.y),
|
||||
r_bl,
|
||||
clip.inset.wz,
|
||||
vec2(-1.0, 1.0),
|
||||
clip.shape.w);
|
||||
+#else
|
||||
+ vClipCenter_Radius_TL = vec4(clip.rect.p0 + r_tl,
|
||||
+ inverse_radii_squared(r_tl));
|
||||
+
|
||||
+ vClipCenter_Radius_TR = vec4(clip.rect.p1.x - r_tr.x,
|
||||
+ clip.rect.p0.y + r_tr.y,
|
||||
+ inverse_radii_squared(r_tr));
|
||||
+
|
||||
+ vClipCenter_Radius_BR = vec4(clip.rect.p1 - r_br,
|
||||
+ inverse_radii_squared(r_br));
|
||||
+
|
||||
+ vClipCenter_Radius_BL = vec4(clip.rect.p0.x + r_bl.x,
|
||||
+ clip.rect.p1.y - r_bl.y,
|
||||
+ inverse_radii_squared(r_bl));
|
||||
+#endif
|
||||
|
||||
// We need to know the half-spaces of the corners separate from the center
|
||||
// and radius. We compute a point that falls on the diagonal (which is just
|
||||
// an inner vertex pushed out along one axis, but not on both) to get the
|
||||
// plane offset of the half-space. We also compute the direction vector of
|
||||
@@ -170,13 +198,15 @@
|
||||
|
||||
vClipPlane_A = vec4(tl.x, tl.y, tl.z, tr.x);
|
||||
vClipPlane_B = vec4(tr.y, tr.z, br.x, br.y);
|
||||
vClipPlane_C = vec4(br.z, bl.x, bl.y, bl.z);
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipShape = clip.shape;
|
||||
vClipClampedInset = min(clip.inset, 0.0);
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
@@ -205,11 +235,13 @@
|
||||
vec3 plane_tr = vec3(vClipPlane_A.w, vClipPlane_B.x, vClipPlane_B.y);
|
||||
vec3 plane_br = vec3(vClipPlane_B.z, vClipPlane_B.w, vClipPlane_C.x);
|
||||
vec3 plane_bl = vec3(vClipPlane_C.y, vClipPlane_C.z, vClipPlane_C.w);
|
||||
|
||||
float dist;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (vClipShape == vec4(1.0)) {
|
||||
+#endif
|
||||
dist = distance_to_rounded_rect(
|
||||
clip_local_pos,
|
||||
plane_tl,
|
||||
vClipCenter_Radius_TL,
|
||||
plane_tr,
|
||||
@@ -218,10 +250,11 @@
|
||||
vClipCenter_Radius_BR,
|
||||
plane_bl,
|
||||
vClipCenter_Radius_BL,
|
||||
vTransformBounds
|
||||
);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
dist = distance_to_shaped_rect(
|
||||
clip_local_pos,
|
||||
vClipCenter_Radius_TL,
|
||||
vClipCenter_Radius_TR,
|
||||
@@ -230,10 +263,11 @@
|
||||
vTransformBounds,
|
||||
vClipShape,
|
||||
vClipClampedInset
|
||||
);
|
||||
}
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
// Compute AA for the given dist and range.
|
||||
float alpha = distance_aa(aa_range, dist);
|
||||
|
||||
@@ -340,13 +374,13 @@
|
||||
#define AA_RECT(local_pos) \
|
||||
sd_round_box(local_pos, v_clip_size, v_clip_radii)
|
||||
#else
|
||||
// The span fast path only handles elliptical corners. For superellipse
|
||||
// shapes, bail out and let SWGL fall back to the fragment shader.
|
||||
- if (vClipShape != vec4(1.0)) {
|
||||
+ #ifdef WR_FEATURE_SUPERELLIPSE
|
||||
return;
|
||||
- }
|
||||
+ #endif
|
||||
|
||||
// Unpack the corner half-spaces packed into vClipPlane_A/B/C.
|
||||
vec3 plane_tl = vec3(vClipPlane_A.x, vClipPlane_A.y, vClipPlane_A.z);
|
||||
vec3 plane_tr = vec3(vClipPlane_A.w, vClipPlane_B.x, vClipPlane_B.y);
|
||||
vec3 plane_br = vec3(vClipPlane_B.z, vClipPlane_B.w, vClipPlane_C.x);
|
||||
diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs
|
||||
--- a/gfx/wr/webrender/src/batch.rs
|
||||
+++ b/gfx/wr/webrender/src/batch.rs
|
||||
@@ -1224,25 +1224,29 @@
|
||||
/// A list of clip instances to be drawn into a target.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct ClipMaskInstanceList {
|
||||
pub mask_instances_fast: FrameVec<MaskInstance>,
|
||||
+ pub mask_instances_superellipse: FrameVec<MaskInstance>,
|
||||
pub mask_instances_slow: FrameVec<MaskInstance>,
|
||||
|
||||
pub mask_instances_fast_with_scissor: FastHashMap<DeviceIntRect, FrameVec<MaskInstance>>,
|
||||
+ pub mask_instances_superellipse_with_scissor: FastHashMap<DeviceIntRect, FrameVec<MaskInstance>>,
|
||||
pub mask_instances_slow_with_scissor: FastHashMap<DeviceIntRect, FrameVec<MaskInstance>>,
|
||||
|
||||
pub image_mask_instances: FastHashMap<TextureSource, FrameVec<PrimitiveInstanceData>>,
|
||||
pub image_mask_instances_with_scissor: FastHashMap<(DeviceIntRect, TextureSource), FrameVec<PrimitiveInstanceData>>,
|
||||
}
|
||||
|
||||
impl ClipMaskInstanceList {
|
||||
pub fn new(memory: &FrameMemory) -> Self {
|
||||
ClipMaskInstanceList {
|
||||
mask_instances_fast: memory.new_vec(),
|
||||
+ mask_instances_superellipse: memory.new_vec(),
|
||||
mask_instances_slow: memory.new_vec(),
|
||||
mask_instances_fast_with_scissor: FastHashMap::default(),
|
||||
+ mask_instances_superellipse_with_scissor: FastHashMap::default(),
|
||||
mask_instances_slow_with_scissor: FastHashMap::default(),
|
||||
image_mask_instances: FastHashMap::default(),
|
||||
image_mask_instances_with_scissor: FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
@@ -1250,20 +1254,24 @@
|
||||
pub fn is_empty(&self) -> bool {
|
||||
// Destructure self to make sure we don't forget to update this method if
|
||||
// a new member is added.
|
||||
let ClipMaskInstanceList {
|
||||
mask_instances_fast,
|
||||
+ mask_instances_superellipse,
|
||||
mask_instances_slow,
|
||||
mask_instances_fast_with_scissor,
|
||||
+ mask_instances_superellipse_with_scissor,
|
||||
mask_instances_slow_with_scissor,
|
||||
image_mask_instances,
|
||||
image_mask_instances_with_scissor,
|
||||
} = self;
|
||||
|
||||
mask_instances_fast.is_empty()
|
||||
+ && mask_instances_superellipse.is_empty()
|
||||
&& mask_instances_slow.is_empty()
|
||||
&& mask_instances_fast_with_scissor.is_empty()
|
||||
+ && mask_instances_superellipse_with_scissor.is_empty()
|
||||
&& mask_instances_slow_with_scissor.is_empty()
|
||||
&& image_mask_instances.is_empty()
|
||||
&& image_mask_instances_with_scissor.is_empty()
|
||||
}
|
||||
}
|
||||
diff --git a/gfx/wr/webrender/src/quad.rs b/gfx/wr/webrender/src/quad.rs
|
||||
--- a/gfx/wr/webrender/src/quad.rs
|
||||
+++ b/gfx/wr/webrender/src/quad.rs
|
||||
@@ -1807,11 +1807,11 @@
|
||||
gpu_buffer: &mut GpuBufferBuilderF,
|
||||
clip_rect: LayoutRect,
|
||||
radius: &BorderRadius,
|
||||
inset: LayoutSideOffsets,
|
||||
mode: ClipMode,
|
||||
-) -> (GpuBufferAddress, bool) {
|
||||
+) -> (GpuBufferAddress, bool, bool) {
|
||||
let radius = clamped_radius(radius, clip_rect.size());
|
||||
|
||||
if radius.can_use_fast_path_in(&clip_rect) {
|
||||
let mut writer = gpu_buffer.write_blocks(3);
|
||||
writer.push_one(clip_rect);
|
||||
@@ -1821,13 +1821,15 @@
|
||||
radius.bottom_left.width,
|
||||
radius.top_left.width,
|
||||
]);
|
||||
writer.push_one([mode as i32 as f32, 0.0, 0.0, 0.0]);
|
||||
|
||||
- (writer.finish(), true)
|
||||
+ (writer.finish(), true, false)
|
||||
} else {
|
||||
- let mut writer = gpu_buffer.write_blocks(6);
|
||||
+ let superellipse = !radius.shapes_all_round();
|
||||
+ let block_count = if superellipse { 6 } else { 4 };
|
||||
+ let mut writer = gpu_buffer.write_blocks(block_count);
|
||||
writer.push_one(clip_rect);
|
||||
writer.push_one([
|
||||
radius.top_left.width,
|
||||
radius.top_left.height,
|
||||
radius.top_right.width,
|
||||
@@ -1838,19 +1840,21 @@
|
||||
radius.bottom_left.height,
|
||||
radius.bottom_right.width,
|
||||
radius.bottom_right.height,
|
||||
]);
|
||||
writer.push_one([mode as i32 as f32, 0.0, 0.0, 0.0]);
|
||||
- writer.push_one([
|
||||
- radius.shape_top_left,
|
||||
- radius.shape_top_right,
|
||||
- radius.shape_bottom_right,
|
||||
- radius.shape_bottom_left,
|
||||
- ]);
|
||||
- writer.push_one(inset);
|
||||
+ if superellipse {
|
||||
+ writer.push_one([
|
||||
+ radius.shape_top_left,
|
||||
+ radius.shape_top_right,
|
||||
+ radius.shape_bottom_right,
|
||||
+ radius.shape_bottom_left,
|
||||
+ ]);
|
||||
+ writer.push_one(inset);
|
||||
+ }
|
||||
|
||||
- (writer.finish(), false)
|
||||
+ (writer.finish(), false, superellipse)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_clip_task(
|
||||
clip_instance: &ClipNodeInstance,
|
||||
@@ -1865,11 +1869,11 @@
|
||||
gpu_buffer: &mut GpuBufferBuilderF,
|
||||
transforms: &mut TransformPalette,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
sub_tasks: &mut SubTaskRange,
|
||||
) {
|
||||
- let (clip_address, fast_path) = match clip_item.kind {
|
||||
+ let (clip_address, fast_path, superellipse) = match clip_item.kind {
|
||||
ClipItemKind::RoundedRectangle { radius, inset, mode } => {
|
||||
write_rounded_rect_clip_blocks(
|
||||
gpu_buffer,
|
||||
clip_instance.clip_rect,
|
||||
&radius,
|
||||
@@ -1882,11 +1886,11 @@
|
||||
writer.push_one(clip_instance.clip_rect);
|
||||
writer.push_one([0.0, 0.0, 0.0, 0.0]);
|
||||
writer.push_one([mode as i32 as f32, 0.0, 0.0, 0.0]);
|
||||
let clip_address = writer.finish();
|
||||
|
||||
- (clip_address, true)
|
||||
+ (clip_address, true, false)
|
||||
}
|
||||
ClipItemKind::Image { .. } => {
|
||||
let transform_id = transforms.gpu.get_id_with_post_scale(
|
||||
clip_instance.spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
@@ -2033,10 +2037,11 @@
|
||||
clip_transform_id,
|
||||
quad_flags,
|
||||
clip_space,
|
||||
needs_scissor_rect,
|
||||
rounded_rect_fast_path: fast_path,
|
||||
+ rounded_rect_superellipse: superellipse,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
fn create_quad_primitive(
|
||||
diff --git a/gfx/wr/webrender/src/render_target.rs b/gfx/wr/webrender/src/render_target.rs
|
||||
--- a/gfx/wr/webrender/src/render_target.rs
|
||||
+++ b/gfx/wr/webrender/src/render_target.rs
|
||||
@@ -441,11 +441,11 @@
|
||||
// so the target must be initialized to one.
|
||||
self.clears.push((target_rect, ColorF::WHITE));
|
||||
|
||||
let device_rect = DeviceRect::from_size(target_rect.size().to_f32());
|
||||
|
||||
- let (clip_address, fast_path) = quad::write_rounded_rect_clip_blocks(
|
||||
+ let (clip_address, fast_path, superellipse) = quad::write_rounded_rect_clip_blocks(
|
||||
&mut gpu_buffer_builder.f32,
|
||||
region_task.clip_rect,
|
||||
®ion_task.radius,
|
||||
region_task.inset,
|
||||
region_task.mode,
|
||||
@@ -495,10 +495,12 @@
|
||||
unused: 0,
|
||||
};
|
||||
|
||||
if fast_path {
|
||||
self.clip_masks.mask_instances_fast.push(instance);
|
||||
+ } else if superellipse {
|
||||
+ self.clip_masks.mask_instances_superellipse.push(instance);
|
||||
} else {
|
||||
self.clip_masks.mask_instances_slow.push(instance);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -925,19 +927,26 @@
|
||||
if task.rounded_rect_fast_path {
|
||||
results.mask_instances_fast_with_scissor
|
||||
.entry(*target_rect)
|
||||
.or_insert_with(|| memory.new_vec())
|
||||
.push(instance);
|
||||
+ } else if task.rounded_rect_superellipse {
|
||||
+ results.mask_instances_superellipse_with_scissor
|
||||
+ .entry(*target_rect)
|
||||
+ .or_insert_with(|| memory.new_vec())
|
||||
+ .push(instance);
|
||||
} else {
|
||||
results.mask_instances_slow_with_scissor
|
||||
.entry(*target_rect)
|
||||
.or_insert_with(|| memory.new_vec())
|
||||
.push(instance);
|
||||
}
|
||||
} else {
|
||||
if task.rounded_rect_fast_path {
|
||||
results.mask_instances_fast.push(instance);
|
||||
+ } else if task.rounded_rect_superellipse {
|
||||
+ results.mask_instances_superellipse.push(instance);
|
||||
} else {
|
||||
results.mask_instances_slow.push(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/gfx/wr/webrender/src/render_task.rs b/gfx/wr/webrender/src/render_task.rs
|
||||
--- a/gfx/wr/webrender/src/render_task.rs
|
||||
+++ b/gfx/wr/webrender/src/render_task.rs
|
||||
@@ -2240,10 +2240,11 @@
|
||||
/// Transform from the quad primitive's space to the clip's local space.
|
||||
pub clip_transform_id: GpuTransformId,
|
||||
pub quad_flags: QuadFlags,
|
||||
pub needs_scissor_rect: bool,
|
||||
pub rounded_rect_fast_path: bool,
|
||||
+ pub rounded_rect_superellipse: bool,
|
||||
}
|
||||
|
||||
/// An clip applied to a render task using the multiply blend mode on top of
|
||||
/// the content being clipped.
|
||||
#[derive(Debug)]
|
||||
diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/mod.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
@@ -2450,10 +2450,54 @@
|
||||
}
|
||||
|
||||
self.device.disable_scissor();
|
||||
}
|
||||
|
||||
+ if !masks.mask_instances_superellipse.is_empty() {
|
||||
+ self.shaders.borrow_mut().ps_mask_superellipse().bind(
|
||||
+ &mut self.device,
|
||||
+ projection,
|
||||
+ None,
|
||||
+ &mut self.renderer_errors,
|
||||
+ &mut self.profile,
|
||||
+ &mut self.command_log,
|
||||
+ );
|
||||
+
|
||||
+ self.draw_instanced_batch(
|
||||
+ &masks.mask_instances_superellipse,
|
||||
+ VertexArrayKind::Mask,
|
||||
+ &BatchTextures::empty(),
|
||||
+ stats,
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ if !masks.mask_instances_superellipse_with_scissor.is_empty() {
|
||||
+ self.shaders.borrow_mut().ps_mask_superellipse().bind(
|
||||
+ &mut self.device,
|
||||
+ projection,
|
||||
+ None,
|
||||
+ &mut self.renderer_errors,
|
||||
+ &mut self.profile,
|
||||
+ &mut self.command_log,
|
||||
+ );
|
||||
+
|
||||
+ self.device.enable_scissor();
|
||||
+
|
||||
+ for (scissor_rect, instances) in &masks.mask_instances_superellipse_with_scissor {
|
||||
+ self.device.set_scissor_rect(draw_target.to_framebuffer_rect(*scissor_rect));
|
||||
+
|
||||
+ self.draw_instanced_batch(
|
||||
+ instances,
|
||||
+ VertexArrayKind::Mask,
|
||||
+ &BatchTextures::empty(),
|
||||
+ stats,
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ self.device.disable_scissor();
|
||||
+ }
|
||||
+
|
||||
if !masks.image_mask_instances.is_empty() {
|
||||
self.shaders.borrow_mut().ps_quad_textured().bind(
|
||||
&mut self.device,
|
||||
projection,
|
||||
None,
|
||||
diff --git a/gfx/wr/webrender/src/renderer/shade.rs b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/shade.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
@@ -65,10 +65,11 @@
|
||||
];
|
||||
|
||||
const DITHERING_FEATURE: &str = "DITHERING";
|
||||
const DUAL_SOURCE_FEATURE: &str = "DUAL_SOURCE_BLENDING";
|
||||
const FAST_PATH_FEATURE: &str = "FAST_PATH";
|
||||
+const SUPERELLIPSE_FEATURE: &str = "SUPERELLIPSE";
|
||||
|
||||
pub(crate) enum ShaderKind {
|
||||
Primitive,
|
||||
Cache(VertexArrayKind),
|
||||
Text,
|
||||
@@ -449,10 +450,11 @@
|
||||
ps_quad_backdrop: ShaderHandle,
|
||||
ps_quad_blend: ShaderHandle,
|
||||
ps_quad_mix_blend: ShaderHandle,
|
||||
ps_mask: ShaderHandle,
|
||||
ps_mask_fast: ShaderHandle,
|
||||
+ ps_mask_superellipse: ShaderHandle,
|
||||
ps_clear: ShaderHandle,
|
||||
ps_copy: ShaderHandle,
|
||||
|
||||
composite: CompositorShaders,
|
||||
}
|
||||
@@ -514,10 +516,17 @@
|
||||
"ps_quad_mask",
|
||||
&[FAST_PATH_FEATURE],
|
||||
&shader_list,
|
||||
)?;
|
||||
|
||||
+ let ps_mask_superellipse = loader.create_shader(
|
||||
+ ShaderKind::Cache(VertexArrayKind::Mask),
|
||||
+ "ps_quad_mask",
|
||||
+ &[SUPERELLIPSE_FEATURE],
|
||||
+ &shader_list,
|
||||
+ )?;
|
||||
+
|
||||
let mut cs_scale = Vec::new();
|
||||
let scale_shader_num = IMAGE_BUFFER_KINDS.len();
|
||||
// PrimitiveShader is not clonable. Use push() to initialize the vec.
|
||||
for _ in 0 .. scale_shader_num {
|
||||
cs_scale.push(None);
|
||||
@@ -786,10 +795,11 @@
|
||||
ps_quad_backdrop,
|
||||
ps_quad_blend,
|
||||
ps_quad_mix_blend,
|
||||
ps_mask,
|
||||
ps_mask_fast,
|
||||
+ ps_mask_superellipse,
|
||||
ps_split_composite,
|
||||
ps_clear,
|
||||
ps_copy,
|
||||
composite,
|
||||
})
|
||||
@@ -963,10 +973,11 @@
|
||||
pub fn ps_quad_textured(&mut self) -> &mut LazilyCompiledShader {
|
||||
self.loader.get(self.ps_quad_textured)
|
||||
}
|
||||
pub fn ps_mask(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.ps_mask) }
|
||||
pub fn ps_mask_fast(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.ps_mask_fast) }
|
||||
+ pub fn ps_mask_superellipse(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.ps_mask_superellipse) }
|
||||
pub fn ps_clear(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.ps_clear) }
|
||||
pub fn ps_copy(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.ps_copy) }
|
||||
|
||||
pub fn deinit(self, device: &mut Device) {
|
||||
self.loader.deinit(device);
|
||||
diff --git a/gfx/wr/webrender_build/src/shader_features.rs b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
--- a/gfx/wr/webrender_build/src/shader_features.rs
|
||||
+++ b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
@@ -65,11 +65,11 @@
|
||||
let mut shaders = ShaderFeatures::new();
|
||||
|
||||
// Cache shaders
|
||||
shaders.insert("cs_blur", vec!["ALPHA_TARGET".to_string(), "COLOR_TARGET".to_string()]);
|
||||
|
||||
- shaders.insert("ps_quad_mask", vec![String::new(), "FAST_PATH".to_string()]);
|
||||
+ shaders.insert("ps_quad_mask", vec![String::new(), "FAST_PATH".to_string(), "SUPERELLIPSE".to_string()]);
|
||||
|
||||
for name in &[
|
||||
"cs_line_decoration",
|
||||
"cs_border_segment",
|
||||
"cs_border_solid",
|
||||
|
||||
307
src/external-patches/firefox/bug_2063169/D319796.patch
Normal file
307
src/external-patches/firefox/bug_2063169/D319796.patch
Normal file
@@ -0,0 +1,307 @@
|
||||
diff --git a/gfx/wr/webrender/res/ps_quad_box_shadow.glsl b/gfx/wr/webrender/res/ps_quad_box_shadow.glsl
|
||||
--- a/gfx/wr/webrender/res/ps_quad_box_shadow.glsl
|
||||
+++ b/gfx/wr/webrender/res/ps_quad_box_shadow.glsl
|
||||
@@ -49,22 +49,26 @@
|
||||
flat varying highp vec4 vElemCenter_Radius_TL;
|
||||
flat varying highp vec4 vElemCenter_Radius_TR;
|
||||
flat varying highp vec4 vElemCenter_Radius_BR;
|
||||
flat varying highp vec4 vElemCenter_Radius_BL;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
flat varying highp vec4 vElemShape;
|
||||
+#endif
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
void pattern_vertex(PrimitiveInfo info) {
|
||||
vec4 data0 = fetch_from_gpu_buffer_1f(info.pattern_input.x);
|
||||
vec4 data1 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 1);
|
||||
vec4 data2 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 2);
|
||||
vec4 data3 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 3);
|
||||
vec4 data4 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 4);
|
||||
vec4 data5 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 5);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vec4 data6 = fetch_from_gpu_buffer_1f(info.pattern_input.x + 6);
|
||||
+#endif
|
||||
|
||||
vec2 alloc_size = data0.xy;
|
||||
vec2 dest_rect_size = data0.zw;
|
||||
vec2 dest_rect_off = data1.xy;
|
||||
v_uv_scale_inset = vec4(vec2(1.0) / alloc_size, data1.z, 0.0);
|
||||
@@ -84,11 +88,11 @@
|
||||
// Map nine-patch UV=1.0 to the true content edge (uv_p0 + content_device_size)
|
||||
// rather than the rounded atlas entry edge (info.segment.uv_rect.p1). The atlas
|
||||
// allocation is rounded up from content_device_size, so this edge always lies
|
||||
// inside the entry; using it keeps the mapping stable to sub-texel precision as
|
||||
// the blur animates (bug 2002194).
|
||||
- vec2 content_device_size = data6.xy;
|
||||
+ vec2 content_device_size = data5.xy;
|
||||
vec2 texture_size = vec2(TEX_SIZE(sColor0));
|
||||
vec2 uv_p0 = info.segment.uv_rect.p0;
|
||||
vec2 uv_p1 = uv_p0 + content_device_size;
|
||||
v_uv_rect = vec4(uv_p0, uv_p1) / texture_size.xyxy;
|
||||
v_uv_bounds = vec4(
|
||||
@@ -110,11 +114,13 @@
|
||||
vElemCenter_Radius_TL = vec4(elem_p0 + r_tl, r_tl);
|
||||
vElemCenter_Radius_TR = vec4(elem_p1.x - r_tr.x, elem_p0.y + r_tr.y, r_tr);
|
||||
vElemCenter_Radius_BR = vec4(elem_p1 - r_br, r_br);
|
||||
vElemCenter_Radius_BL = vec4(elem_p0.x + r_bl.x, elem_p1.y - r_bl.y, r_bl);
|
||||
|
||||
- vElemShape = data5;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
+ vElemShape = data6;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
@@ -170,22 +176,24 @@
|
||||
vec3 elem_plane_bl = vec3(n_bl, dot(n_bl, vec2(c_bl.x, c_bl.y + r_bl.y)));
|
||||
|
||||
// Reconstruct the element rect bounds from the TL and BR corner data.
|
||||
vec4 elem_bounds = vec4(c_tl - r_tl, c_br + r_br);
|
||||
|
||||
- vec4 elem_shape = vElemShape;
|
||||
-
|
||||
float elem_dist;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
+ vec4 elem_shape = vElemShape;
|
||||
if (elem_shape == vec4(1.0)) {
|
||||
+#endif
|
||||
elem_dist = distance_to_rounded_rect(
|
||||
local_pos,
|
||||
elem_plane_tl, vec4(c_tl, inverse_radii_squared(r_tl)),
|
||||
elem_plane_tr, vec4(c_tr, inverse_radii_squared(r_tr)),
|
||||
elem_plane_br, vec4(c_br, inverse_radii_squared(r_br)),
|
||||
elem_plane_bl, vec4(c_bl, inverse_radii_squared(r_bl)),
|
||||
elem_bounds
|
||||
);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
elem_dist = distance_to_shaped_rect(
|
||||
local_pos,
|
||||
vec4(c_tl, elem_shape.x == 1.0 ? inverse_radii_squared(r_tl) : inverse_radii(r_tl)),
|
||||
vec4(c_tr, elem_shape.y == 1.0 ? inverse_radii_squared(r_tr) : inverse_radii(r_tr)),
|
||||
@@ -194,10 +202,11 @@
|
||||
elem_bounds,
|
||||
elem_shape,
|
||||
vec4(0.0)
|
||||
);
|
||||
}
|
||||
+#endif
|
||||
|
||||
// Outset (inset=0): dist < 0 = inside element → should be clipped out → use -elem_dist.
|
||||
// Inset (inset=1): dist < 0 = inside element → should be kept → use elem_dist.
|
||||
float element_clip = distance_aa(aa_range, mix(-elem_dist, elem_dist, inset));
|
||||
|
||||
diff --git a/gfx/wr/webrender/src/pattern/box_shadow.rs b/gfx/wr/webrender/src/pattern/box_shadow.rs
|
||||
--- a/gfx/wr/webrender/src/pattern/box_shadow.rs
|
||||
+++ b/gfx/wr/webrender/src/pattern/box_shadow.rs
|
||||
@@ -41,11 +41,14 @@
|
||||
_sub_rect: Option<DeviceRect>,
|
||||
_offset: LayoutVector2D,
|
||||
_ctx: &PatternBuilderContext,
|
||||
state: &mut PatternBuilderState,
|
||||
) -> Pattern {
|
||||
- let mut writer = state.frame_gpu_data.f32.write_blocks(7);
|
||||
+ let superellipse = !self.element_radius.shapes_all_round();
|
||||
+
|
||||
+ let block_count = if superellipse { 7 } else { 6 };
|
||||
+ let mut writer = state.frame_gpu_data.f32.write_blocks(block_count);
|
||||
writer.push_one([
|
||||
self.shadow_rect_alloc_size.width,
|
||||
self.shadow_rect_alloc_size.height,
|
||||
self.dest_rect_size.width,
|
||||
self.dest_rect_size.height,
|
||||
@@ -72,26 +75,28 @@
|
||||
self.element_radius.bottom_right.width,
|
||||
self.element_radius.bottom_right.height,
|
||||
self.element_radius.bottom_left.width,
|
||||
self.element_radius.bottom_left.height,
|
||||
]);
|
||||
- writer.push_one([
|
||||
- self.element_radius.shape_top_left,
|
||||
- self.element_radius.shape_top_right,
|
||||
- self.element_radius.shape_bottom_right,
|
||||
- self.element_radius.shape_bottom_left,
|
||||
- ]);
|
||||
writer.push_one([
|
||||
self.content_device_size.width,
|
||||
self.content_device_size.height,
|
||||
0.0,
|
||||
0.0,
|
||||
]);
|
||||
+ if superellipse {
|
||||
+ writer.push_one([
|
||||
+ self.element_radius.shape_top_left,
|
||||
+ self.element_radius.shape_top_right,
|
||||
+ self.element_radius.shape_bottom_right,
|
||||
+ self.element_radius.shape_bottom_left,
|
||||
+ ]);
|
||||
+ }
|
||||
let addr = writer.finish();
|
||||
|
||||
Pattern {
|
||||
- kind: PatternKind::BoxShadow,
|
||||
+ kind: if superellipse { PatternKind::BoxShadowSuperellipse } else { PatternKind::BoxShadow },
|
||||
shader_input: PatternShaderInput(addr.as_int(), 0),
|
||||
texture_input: PatternTextureInput::new(self.render_task),
|
||||
base_color: self.color,
|
||||
is_opaque: false,
|
||||
blend_mode: BlendMode::PremultipliedAlpha,
|
||||
diff --git a/gfx/wr/webrender/src/pattern/mod.rs b/gfx/wr/webrender/src/pattern/mod.rs
|
||||
--- a/gfx/wr/webrender/src/pattern/mod.rs
|
||||
+++ b/gfx/wr/webrender/src/pattern/mod.rs
|
||||
@@ -29,36 +29,37 @@
|
||||
Gradient = 1,
|
||||
Repeat = 2,
|
||||
|
||||
Mask = 3,
|
||||
BoxShadow = 4,
|
||||
+ BoxShadowSuperellipse = 5,
|
||||
// Variants of ColorOrTexture that use a non-default sampler type
|
||||
// (samplerExternalOES / __samplerExternal2DY2YEXT / sampler2DRect). The
|
||||
// quad shader is compiled in matching per-kind variants; see
|
||||
// ps_quad_textured.glsl.
|
||||
- TextureExternal = 5,
|
||||
- TextureExternalBT709 = 6,
|
||||
- TextureRect = 7,
|
||||
+ TextureExternal = 6,
|
||||
+ TextureExternalBT709 = 7,
|
||||
+ TextureRect = 8,
|
||||
// Samples up to three planes (sColor0/1/2) and converts from YUV to RGB.
|
||||
// Like ColorOrTexture, the YUV pattern comes in sampler-type-specific
|
||||
// variants so that the planes are sampled with the matching sColor
|
||||
// declaration; see ps_quad_yuv.glsl. `Yuv` is the default (TEXTURE_2D).
|
||||
- Yuv = 8,
|
||||
- YuvTextureExternal = 9,
|
||||
- YuvTextureExternalBT709 = 10,
|
||||
- YuvTextureRect = 11,
|
||||
+ Yuv = 9,
|
||||
+ YuvTextureExternal = 10,
|
||||
+ YuvTextureExternalBT709 = 11,
|
||||
+ YuvTextureRect = 12,
|
||||
// Samples a captured backdrop texture using a (bilerp) 4-corner uv quad.
|
||||
- Backdrop = 12,
|
||||
+ Backdrop = 13,
|
||||
// Applies a filter to a sampled source texture; see ps_quad_blend.glsl.
|
||||
- Blend = 13,
|
||||
+ Blend = 14,
|
||||
// Composites a picture over its backdrop with a software mix-blend-mode;
|
||||
// samples two textures (backdrop + source). See ps_quad_mix_blend.glsl.
|
||||
- MixBlend = 14,
|
||||
+ MixBlend = 15,
|
||||
// When adding patterns, don't forget to update the NUM_PATTERNS constant.
|
||||
}
|
||||
|
||||
-pub const NUM_PATTERNS: u32 = 15;
|
||||
+pub const NUM_PATTERNS: u32 = 16;
|
||||
|
||||
impl PatternKind {
|
||||
pub fn from_u32(val: u32) -> Self {
|
||||
assert!(val < NUM_PATTERNS);
|
||||
unsafe { std::mem::transmute(val) }
|
||||
diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/mod.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
@@ -251,10 +251,11 @@
|
||||
BatchKind::Quad(PatternKind::TextureExternalBT709) => GPU_TAG_PRIMITIVE,
|
||||
BatchKind::Quad(PatternKind::TextureRect) => GPU_TAG_PRIMITIVE,
|
||||
BatchKind::Quad(PatternKind::Gradient) => GPU_TAG_GRADIENT,
|
||||
BatchKind::Quad(PatternKind::Repeat) => GPU_TAG_REPEAT,
|
||||
BatchKind::Quad(PatternKind::BoxShadow) => GPU_TAG_PRIMITIVE,
|
||||
+ BatchKind::Quad(PatternKind::BoxShadowSuperellipse) => GPU_TAG_PRIMITIVE,
|
||||
BatchKind::Quad(PatternKind::Yuv) => GPU_TAG_BRUSH_YUV_IMAGE,
|
||||
BatchKind::Quad(PatternKind::YuvTextureExternal) => GPU_TAG_BRUSH_YUV_IMAGE,
|
||||
BatchKind::Quad(PatternKind::YuvTextureExternalBT709) => GPU_TAG_BRUSH_YUV_IMAGE,
|
||||
BatchKind::Quad(PatternKind::YuvTextureRect) => GPU_TAG_BRUSH_YUV_IMAGE,
|
||||
BatchKind::Quad(PatternKind::Backdrop) => GPU_TAG_PRIMITIVE,
|
||||
diff --git a/gfx/wr/webrender/src/renderer/shade.rs b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/shade.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
@@ -438,10 +438,11 @@
|
||||
ps_quad_textured_external_bt709: Option<ShaderHandle>,
|
||||
ps_quad_textured_rect: Option<ShaderHandle>,
|
||||
ps_quad_repeat: ShaderHandle,
|
||||
ps_quad_gradient: ShaderHandle,
|
||||
ps_quad_box_shadow: ShaderHandle,
|
||||
+ ps_quad_box_shadow_superellipse: ShaderHandle,
|
||||
// ps_quad_yuv, like ps_quad_textured, comes in sampler-type-specific
|
||||
// variants so the YUV planes are sampled with the matching sColor
|
||||
// declaration. The variant is selected via PatternKind.
|
||||
ps_quad_yuv: ShaderHandle,
|
||||
ps_quad_yuv_external: Option<ShaderHandle>,
|
||||
@@ -651,10 +652,17 @@
|
||||
"ps_quad_box_shadow",
|
||||
&[],
|
||||
&shader_list,
|
||||
)?;
|
||||
|
||||
+ let ps_quad_box_shadow_superellipse = loader.create_shader(
|
||||
+ ShaderKind::Primitive,
|
||||
+ "ps_quad_box_shadow",
|
||||
+ &[SUPERELLIPSE_FEATURE],
|
||||
+ &shader_list,
|
||||
+ )?;
|
||||
+
|
||||
let ps_quad_yuv = loader.create_shader(
|
||||
ShaderKind::Primitive,
|
||||
"ps_quad_yuv",
|
||||
&["TEXTURE_2D"],
|
||||
&shader_list,
|
||||
@@ -786,10 +794,11 @@
|
||||
ps_quad_textured_external_bt709,
|
||||
ps_quad_textured_rect,
|
||||
ps_quad_repeat,
|
||||
ps_quad_gradient,
|
||||
ps_quad_box_shadow,
|
||||
+ ps_quad_box_shadow_superellipse,
|
||||
ps_quad_yuv,
|
||||
ps_quad_yuv_external,
|
||||
ps_quad_yuv_external_bt709,
|
||||
ps_quad_yuv_rect,
|
||||
ps_quad_backdrop,
|
||||
@@ -867,10 +876,11 @@
|
||||
PatternKind::TextureRect => self.ps_quad_textured_rect
|
||||
.expect("bug: ps_quad_textured TEXTURE_RECT variant not loaded"),
|
||||
PatternKind::Gradient => self.ps_quad_gradient,
|
||||
PatternKind::Repeat => self.ps_quad_repeat,
|
||||
PatternKind::BoxShadow => self.ps_quad_box_shadow,
|
||||
+ PatternKind::BoxShadowSuperellipse => self.ps_quad_box_shadow_superellipse,
|
||||
PatternKind::Yuv => self.ps_quad_yuv,
|
||||
PatternKind::YuvTextureExternal => self.ps_quad_yuv_external
|
||||
.expect("bug: ps_quad_yuv TEXTURE_EXTERNAL variant not loaded"),
|
||||
PatternKind::YuvTextureExternalBT709 => self.ps_quad_yuv_external_bt709
|
||||
.expect("bug: ps_quad_yuv TEXTURE_EXTERNAL_BT709 variant not loaded"),
|
||||
@@ -923,10 +933,13 @@
|
||||
self.ps_quad_repeat
|
||||
}
|
||||
BatchKind::Quad(PatternKind::BoxShadow) => {
|
||||
self.ps_quad_box_shadow
|
||||
}
|
||||
+ BatchKind::Quad(PatternKind::BoxShadowSuperellipse) => {
|
||||
+ self.ps_quad_box_shadow_superellipse
|
||||
+ }
|
||||
BatchKind::Quad(PatternKind::Yuv) => {
|
||||
self.ps_quad_yuv
|
||||
}
|
||||
BatchKind::Quad(PatternKind::YuvTextureExternal) => {
|
||||
self.ps_quad_yuv_external
|
||||
diff --git a/gfx/wr/webrender_build/src/shader_features.rs b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
--- a/gfx/wr/webrender_build/src/shader_features.rs
|
||||
+++ b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
@@ -166,11 +166,11 @@
|
||||
}
|
||||
shaders.insert("ps_quad_textured", ps_quad_textured_features);
|
||||
|
||||
shaders.insert("ps_quad_repeat", vec![base_prim_features.finish()]);
|
||||
|
||||
- shaders.insert("ps_quad_box_shadow", vec![base_prim_features.finish()]);
|
||||
+ shaders.insert("ps_quad_box_shadow", vec![base_prim_features.finish(), "SUPERELLIPSE".to_string()]);
|
||||
|
||||
// Like ps_quad_textured, ps_quad_yuv needs per-texture-kind variants so that
|
||||
// the YUV planes are sampled with the correct sampler type.
|
||||
let mut ps_quad_yuv_features: Vec<String> = vec!["TEXTURE_2D".to_string()];
|
||||
if flags.contains(ShaderFeatureFlags::GL) {
|
||||
|
||||
560
src/external-patches/firefox/bug_2063169/D319869.patch
Normal file
560
src/external-patches/firefox/bug_2063169/D319869.patch
Normal file
@@ -0,0 +1,560 @@
|
||||
diff --git a/gfx/wr/webrender/res/border_shared.glsl b/gfx/wr/webrender/res/border_shared.glsl
|
||||
--- a/gfx/wr/webrender/res/border_shared.glsl
|
||||
+++ b/gfx/wr/webrender/res/border_shared.glsl
|
||||
@@ -27,25 +27,33 @@
|
||||
vec4 rect;
|
||||
vec4 color0;
|
||||
vec4 color1;
|
||||
vec2 widths;
|
||||
vec2 radii;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
float shape;
|
||||
vec2 shape_offset;
|
||||
vec2 inset;
|
||||
+#endif
|
||||
};
|
||||
|
||||
BorderInstanceGpuData fetch_gpu_data(int index) {
|
||||
BorderInstanceGpuData data;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vec4 texels[6] = fetch_from_gpu_buffer_6f(index);
|
||||
+#else
|
||||
+ vec4 texels[4] = fetch_from_gpu_buffer_4f(index);
|
||||
+#endif
|
||||
data.rect = texels[0];
|
||||
data.color0 = texels[1];
|
||||
data.color1 = texels[2];
|
||||
data.widths = texels[3].xy;
|
||||
data.radii = texels[3].zw;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
data.shape = texels[4].x;
|
||||
data.shape_offset = texels[4].yz;
|
||||
data.inset = texels[5].xy;
|
||||
+#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
diff --git a/gfx/wr/webrender/res/cs_border_segment.glsl b/gfx/wr/webrender/res/cs_border_segment.glsl
|
||||
--- a/gfx/wr/webrender/res/cs_border_segment.glsl
|
||||
+++ b/gfx/wr/webrender/res/cs_border_segment.glsl
|
||||
@@ -30,11 +30,13 @@
|
||||
flat varying highp vec4 vClipCenter_Sign;
|
||||
|
||||
// An outer and inner elliptical radii for border
|
||||
// corner clipping.
|
||||
flat varying highp vec4 vClipRadii;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
flat varying highp vec4 vClipOffsets;
|
||||
+#endif
|
||||
|
||||
// Reference point for determine edge clip lines.
|
||||
flat varying highp vec4 vEdgeReference;
|
||||
|
||||
// Stores widths/2 and widths/3 to save doing this in FS.
|
||||
@@ -192,26 +194,34 @@
|
||||
vColor00 = color0[0];
|
||||
vColor01 = color0[1];
|
||||
vec4[2] color1 = get_colors_for_side(data.color1, style1);
|
||||
vColor10 = color1[0];
|
||||
vColor11 = color1[1];
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipCenter_Sign = vec4(outer + clip_sign * (data.radii + data.shape_offset), clip_sign);
|
||||
+#else
|
||||
+ vClipCenter_Sign = vec4(outer + clip_sign * data.radii, clip_sign);
|
||||
+#endif
|
||||
vClipRadii = vec4(data.radii, max(data.radii - data.widths, 0.0));
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipOffsets = vec4(0.0);
|
||||
+#endif
|
||||
vColorLine = vec4(outer, data.widths.y * -clip_sign.y, data.widths.x * clip_sign.x);
|
||||
vEdgeReference = vec4(edge_reference, edge_reference + data.widths);
|
||||
vClipParams1 = aClipParams1;
|
||||
vClipParams2 = aClipParams2;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape != 1.0)
|
||||
{
|
||||
vec2 reference_radii = (data.radii == vec2(0.0)) ? vec2(0.0) : data.radii + data.inset;
|
||||
vec4 contour1 = compute_contoured_superellipse(reference_radii, data.shape, data.inset);
|
||||
vec4 contour2 = compute_contoured_superellipse(reference_radii, data.shape, data.inset + data.widths);
|
||||
vClipOffsets = vec4(contour1.xy, contour2.xy);
|
||||
vClipRadii = vec4(contour1.zw, contour2.zw);
|
||||
}
|
||||
+#endif
|
||||
|
||||
// For the case of dot and dash clips, optimize the number of pixels that
|
||||
// are hit to just include the dot itself.
|
||||
if (clip_mode == CLIP_DOT) {
|
||||
float radius = aClipParams1.z;
|
||||
@@ -258,19 +268,22 @@
|
||||
// also 0.67 of the radii. Use these to form a
|
||||
// SDF subtraction which will clip out the inside
|
||||
// third of the rounded edge.
|
||||
float d_radii_a;
|
||||
float d_radii_b;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape == 1.0) {
|
||||
+#endif
|
||||
d_radii_a = distance_to_ellipse(
|
||||
clip_relative_pos,
|
||||
clip_radii.xy - vPartialWidths.xy
|
||||
);
|
||||
d_radii_b = distance_to_ellipse(
|
||||
clip_relative_pos,
|
||||
clip_radii.xy - 2.0 * vPartialWidths.xy
|
||||
);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
d_radii_a = distance_to_superellipse(
|
||||
clip_relative_pos - mix(vClipOffsets.xy, vClipOffsets.zw, 1.0 / 3.0),
|
||||
mix(clip_radii.xy, clip_radii.zw, 1.0 / 3.0),
|
||||
data.shape
|
||||
@@ -286,24 +299,28 @@
|
||||
d_radii_a = max(d_radii_a, -min(included_region_a.x, included_region_a.y));
|
||||
|
||||
vec2 included_region_b = data.radii - 2.0 * vPartialWidths.xy - clip_relative_pos;
|
||||
d_radii_b = max(d_radii_b, -min(included_region_b.x, included_region_b.y));
|
||||
}
|
||||
+#endif
|
||||
|
||||
float d = min(-d_radii_a, d_radii_b);
|
||||
|
||||
color0 *= distance_aa(aa_range, d);
|
||||
break;
|
||||
}
|
||||
case BORDER_STYLE_GROOVE:
|
||||
case BORDER_STYLE_RIDGE: {
|
||||
float d;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape == 1.0) {
|
||||
+#endif
|
||||
d = distance_to_ellipse(
|
||||
clip_relative_pos,
|
||||
clip_radii.xy - vPartialWidths.zw
|
||||
);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
d = distance_to_superellipse(
|
||||
clip_relative_pos - mix(vClipOffsets.xy, vClipOffsets.zw, 0.5),
|
||||
mix(clip_radii.xy, clip_radii.zw, 0.5),
|
||||
data.shape
|
||||
@@ -311,10 +328,11 @@
|
||||
|
||||
// Clamp to the middle of the adjacent borders
|
||||
vec2 included_region = data.radii - vPartialWidths.zw - clip_relative_pos;
|
||||
d = max(d, -min(included_region.x, included_region.y));
|
||||
}
|
||||
+#endif
|
||||
float alpha = distance_aa(aa_range, d);
|
||||
float swizzled_factor;
|
||||
switch (segment) {
|
||||
case SEGMENT_TOP_LEFT: swizzled_factor = 0.0; break;
|
||||
case SEGMENT_TOP_RIGHT: swizzled_factor = mix_factor; break;
|
||||
@@ -435,22 +453,26 @@
|
||||
|
||||
if (in_clip_region) {
|
||||
float d_radii_a;
|
||||
float d_radii_b;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape == 1.0) {
|
||||
+#endif
|
||||
d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy);
|
||||
d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
clip_relative_pos = abs(clip_relative_pos) - data.shape_offset;
|
||||
d_radii_a = distance_to_superellipse(clip_relative_pos - vClipOffsets.xy, vClipRadii.xy, data.shape);
|
||||
d_radii_b = distance_to_superellipse(clip_relative_pos - vClipOffsets.zw, vClipRadii.zw, data.shape);
|
||||
|
||||
// exclude the straight border part from the subtracted region
|
||||
vec2 included_region = data.radii - data.widths - clip_relative_pos;
|
||||
d_radii_b = max(d_radii_b, -min(included_region.x, included_region.y));
|
||||
}
|
||||
+#endif
|
||||
|
||||
float d_radii = max(d_radii_a, -d_radii_b);
|
||||
d = max(d, d_radii);
|
||||
|
||||
color0 = evaluate_color_for_style_in_corner(
|
||||
diff --git a/gfx/wr/webrender/res/cs_border_solid.glsl b/gfx/wr/webrender/res/cs_border_solid.glsl
|
||||
--- a/gfx/wr/webrender/res/cs_border_solid.glsl
|
||||
+++ b/gfx/wr/webrender/res/cs_border_solid.glsl
|
||||
@@ -31,11 +31,13 @@
|
||||
flat varying highp vec4 vClipCenter_Sign;
|
||||
|
||||
// An outer and inner elliptical radii for border
|
||||
// corner clipping.
|
||||
flat varying highp vec4 vClipRadii;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
flat varying highp vec4 vClipOffsets;
|
||||
+#endif
|
||||
|
||||
// Position, scale, and radii of horizontally and vertically adjacent corner clips.
|
||||
flat varying highp vec4 vHorizontalClipCenter_Sign;
|
||||
flat varying highp vec2 vHorizontalClipRadii;
|
||||
flat varying highp vec4 vVerticalClipCenter_Sign;
|
||||
@@ -74,11 +76,11 @@
|
||||
void main(void) {
|
||||
BorderInstanceGpuData data = fetch_gpu_data(aGpuDataAddress);
|
||||
vGpuDataAddress.x = aGpuDataAddress;
|
||||
|
||||
int segment = aFlags & 0xff;
|
||||
- bool do_aa = ((aFlags >> 24) & 0xf0) != 0;
|
||||
+ bool do_aa = ((aFlags >> 28) & 0x1) != 0;
|
||||
|
||||
vec2 outer_scale = get_outer_corner_scale(segment);
|
||||
vec2 size = data.rect.zw - data.rect.xy;
|
||||
vec2 outer = outer_scale * size;
|
||||
vec2 clip_sign = 1.0 - 2.0 * outer_scale;
|
||||
@@ -100,23 +102,31 @@
|
||||
vMixColors.x = mix_colors;
|
||||
vPos = size * aPosition.xy;
|
||||
|
||||
vColor0 = data.color0;
|
||||
vColor1 = data.color1;
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipCenter_Sign = vec4(outer + clip_sign * (data.radii + data.shape_offset), clip_sign);
|
||||
+#else
|
||||
+ vClipCenter_Sign = vec4(outer + clip_sign * data.radii, clip_sign);
|
||||
+#endif
|
||||
vClipRadii = vec4(data.radii, max(data.radii - data.widths, 0.0));
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
vClipOffsets = vec4(0.0);
|
||||
+#endif
|
||||
vColorLine = vec4(outer, data.widths.y * -clip_sign.y, data.widths.x * clip_sign.x);
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape != 1.0)
|
||||
{
|
||||
vec2 reference_radii = (data.radii == vec2(0.0)) ? vec2(0.0) : data.radii + data.inset;
|
||||
vec4 contour1 = compute_contoured_superellipse(reference_radii, data.shape, data.inset);
|
||||
vec4 contour2 = compute_contoured_superellipse(reference_radii, data.shape, data.inset + data.widths);
|
||||
vClipOffsets = vec4(contour1.xy, contour2.xy);
|
||||
vClipRadii = vec4(contour1.zw, contour2.zw);
|
||||
}
|
||||
+#endif
|
||||
|
||||
vec2 horizontal_clip_sign = vec2(-clip_sign.x, clip_sign.y);
|
||||
vHorizontalClipCenter_Sign = vec4(aClipParams1.xy +
|
||||
horizontal_clip_sign * aClipParams1.zw,
|
||||
horizontal_clip_sign);
|
||||
@@ -156,22 +166,26 @@
|
||||
float d = -1.0;
|
||||
if (in_clip_region) {
|
||||
float d_radii_a;
|
||||
float d_radii_b;
|
||||
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
if (data.shape == 1.0) {
|
||||
+#endif
|
||||
d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy);
|
||||
d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw);
|
||||
+#ifdef WR_FEATURE_SUPERELLIPSE
|
||||
} else {
|
||||
clip_relative_pos = abs(clip_relative_pos) - data.shape_offset;
|
||||
d_radii_a = distance_to_superellipse(clip_relative_pos - vClipOffsets.xy, vClipRadii.xy, data.shape);
|
||||
d_radii_b = distance_to_superellipse(clip_relative_pos - vClipOffsets.zw, vClipRadii.zw, data.shape);
|
||||
|
||||
// exclude the straight border part from the subtracted region
|
||||
vec2 included_region = data.radii - data.widths - clip_relative_pos;
|
||||
d_radii_b = max(d_radii_b, -min(included_region.x, included_region.y));
|
||||
}
|
||||
+#endif
|
||||
|
||||
d = max(d_radii_a, -d_radii_b);
|
||||
}
|
||||
|
||||
// And again for horizontally-adjacent corner
|
||||
diff --git a/gfx/wr/webrender/src/border.rs b/gfx/wr/webrender/src/border.rs
|
||||
--- a/gfx/wr/webrender/src/border.rs
|
||||
+++ b/gfx/wr/webrender/src/border.rs
|
||||
@@ -855,14 +855,17 @@
|
||||
h_adjacent_corner_radius: DeviceSize,
|
||||
v_adjacent_corner_outer: DevicePoint,
|
||||
v_adjacent_corner_radius: DeviceSize,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
) {
|
||||
+ let superellipse = shape != 1.0;
|
||||
+
|
||||
let base_flags = (segment as i32) |
|
||||
((style0 as i32) << 8) |
|
||||
((style1 as i32) << 16) |
|
||||
- ((do_aa as i32) << 28);
|
||||
+ ((do_aa as i32) << 28) |
|
||||
+ ((superellipse as i32) << 29);
|
||||
|
||||
let instance_gpu_data = BorderInstanceGpuData {
|
||||
local_rect: task_rect,
|
||||
color0: color0.premultiplied(),
|
||||
color1: color1.premultiplied(),
|
||||
@@ -875,11 +878,11 @@
|
||||
|
||||
let base_instance = BorderInstance {
|
||||
task_origin: DevicePoint::zero(),
|
||||
flags: base_flags,
|
||||
clip_params: [0.0; 8],
|
||||
- gpu_data_address: instance_gpu_data.write(gpu_buffer_builder)
|
||||
+ gpu_data_address: instance_gpu_data.write(superellipse, gpu_buffer_builder)
|
||||
};
|
||||
|
||||
match segment {
|
||||
BorderSegment::TopLeft |
|
||||
BorderSegment::TopRight |
|
||||
diff --git a/gfx/wr/webrender/src/gpu_types.rs b/gfx/wr/webrender/src/gpu_types.rs
|
||||
--- a/gfx/wr/webrender/src/gpu_types.rs
|
||||
+++ b/gfx/wr/webrender/src/gpu_types.rs
|
||||
@@ -192,18 +192,21 @@
|
||||
pub shape_offset: DeviceSize,
|
||||
pub inset: DeviceSize,
|
||||
}
|
||||
|
||||
impl BorderInstanceGpuData {
|
||||
- pub fn write(&self, gpu_buffer_builder: &mut GpuBufferBuilderF) -> GpuBufferAddress {
|
||||
- let mut writer = gpu_buffer_builder.write_blocks(6);
|
||||
+ pub fn write(&self, superellipse: bool, gpu_buffer_builder: &mut GpuBufferBuilderF) -> GpuBufferAddress {
|
||||
+ let block_count = if superellipse { 6 } else { 4 };
|
||||
+ let mut writer = gpu_buffer_builder.write_blocks(block_count);
|
||||
writer.push_one(self.local_rect);
|
||||
writer.push_one(self.color0);
|
||||
writer.push_one(self.color1);
|
||||
writer.push_one([self.widths.width, self.widths.height, self.radius.width, self.radius.height]);
|
||||
- writer.push_one([self.shape, self.shape_offset.width, self.shape_offset.height, 0.0]);
|
||||
- writer.push_one([self.inset.width, self.inset.height, 0.0, 0.0]);
|
||||
+ if superellipse {
|
||||
+ writer.push_one([self.shape, self.shape_offset.width, self.shape_offset.height, 0.0]);
|
||||
+ writer.push_one([self.inset.width, self.inset.height, 0.0, 0.0]);
|
||||
+ }
|
||||
|
||||
writer.finish()
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/gfx/wr/webrender/src/render_target.rs b/gfx/wr/webrender/src/render_target.rs
|
||||
--- a/gfx/wr/webrender/src/render_target.rs
|
||||
+++ b/gfx/wr/webrender/src/render_target.rs
|
||||
@@ -33,10 +33,11 @@
|
||||
use crate::spatial_tree::SpatialNodeIndex;
|
||||
|
||||
|
||||
const STYLE_SOLID: i32 = ((BorderStyle::Solid as i32) << 8) | ((BorderStyle::Solid as i32) << 16);
|
||||
const STYLE_MASK: i32 = 0x00FF_FF00;
|
||||
+const SUPERELLIPSE_MASK: i32 = 1 << 29;
|
||||
|
||||
/// A tag used to identify the output format of a `RenderTarget`.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
@@ -163,10 +164,12 @@
|
||||
|
||||
pub clip_masks: ClipMaskInstanceList,
|
||||
|
||||
pub border_segments_complex: FrameVec<BorderInstance>,
|
||||
pub border_segments_solid: FrameVec<BorderInstance>,
|
||||
+ pub border_segments_complex_superellipse: FrameVec<BorderInstance>,
|
||||
+ pub border_segments_solid_superellipse: FrameVec<BorderInstance>,
|
||||
pub line_decorations: FrameVec<LineDecorationJob>,
|
||||
|
||||
// Clearing render targets has a fair amount of special cases.
|
||||
// The general rules are:
|
||||
// - Depth (for at least the used potion of the target) is always cleared if it
|
||||
@@ -223,10 +226,12 @@
|
||||
prim_instances: std::array::from_fn(|_| FastHashMap::default()),
|
||||
prim_instances_with_scissor: FastHashMap::default(),
|
||||
clip_masks: ClipMaskInstanceList::new(memory),
|
||||
border_segments_complex: memory.new_vec(),
|
||||
border_segments_solid: memory.new_vec(),
|
||||
+ border_segments_complex_superellipse: memory.new_vec(),
|
||||
+ border_segments_solid_superellipse: memory.new_vec(),
|
||||
clears: memory.new_vec(),
|
||||
line_decorations: memory.new_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,14 +552,23 @@
|
||||
let instances = task_info.instances.clone();
|
||||
for mut instance in instances {
|
||||
// TODO(gw): It may be better to store the task origin in
|
||||
// the render task data instead of per instance.
|
||||
instance.task_origin = task_origin;
|
||||
+ let superellipse = (instance.flags & SUPERELLIPSE_MASK) != 0;
|
||||
if instance.flags & STYLE_MASK == STYLE_SOLID {
|
||||
- self.border_segments_solid.push(instance);
|
||||
+ if superellipse {
|
||||
+ self.border_segments_solid_superellipse.push(instance);
|
||||
+ } else {
|
||||
+ self.border_segments_solid.push(instance);
|
||||
+ }
|
||||
} else {
|
||||
- self.border_segments_complex.push(instance);
|
||||
+ if superellipse {
|
||||
+ self.border_segments_complex_superellipse.push(instance);
|
||||
+ } else {
|
||||
+ self.border_segments_complex.push(instance);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
RenderTaskKind::Image(..) |
|
||||
RenderTaskKind::Cached(..) |
|
||||
diff --git a/gfx/wr/webrender/src/renderer/mod.rs b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/mod.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/mod.rs
|
||||
@@ -3394,11 +3394,13 @@
|
||||
draw_target,
|
||||
);
|
||||
|
||||
// Draw any borders for this target.
|
||||
if !target.border_segments_solid.is_empty() ||
|
||||
- !target.border_segments_complex.is_empty()
|
||||
+ !target.border_segments_complex.is_empty() ||
|
||||
+ !target.border_segments_solid_superellipse.is_empty() ||
|
||||
+ !target.border_segments_complex_superellipse.is_empty()
|
||||
{
|
||||
let _timer = self.gpu_profiler.start_timer(GPU_TAG_CACHE_BORDER);
|
||||
|
||||
self.set_blend(true, FramebufferKind::Other);
|
||||
self.set_blend_mode_premultiplied_alpha(FramebufferKind::Other);
|
||||
@@ -3437,10 +3439,46 @@
|
||||
&BatchTextures::empty(),
|
||||
stats,
|
||||
);
|
||||
}
|
||||
|
||||
+ if !target.border_segments_solid_superellipse.is_empty() {
|
||||
+ self.shaders.borrow_mut().cs_border_solid_superellipse().bind(
|
||||
+ &mut self.device,
|
||||
+ &projection,
|
||||
+ None,
|
||||
+ &mut self.renderer_errors,
|
||||
+ &mut self.profile,
|
||||
+ &mut self.command_log,
|
||||
+ );
|
||||
+
|
||||
+ self.draw_instanced_batch(
|
||||
+ &target.border_segments_solid_superellipse,
|
||||
+ VertexArrayKind::Border,
|
||||
+ &BatchTextures::empty(),
|
||||
+ stats,
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ if !target.border_segments_complex_superellipse.is_empty() {
|
||||
+ self.shaders.borrow_mut().cs_border_segment_superellipse().bind(
|
||||
+ &mut self.device,
|
||||
+ &projection,
|
||||
+ None,
|
||||
+ &mut self.renderer_errors,
|
||||
+ &mut self.profile,
|
||||
+ &mut self.command_log,
|
||||
+ );
|
||||
+
|
||||
+ self.draw_instanced_batch(
|
||||
+ &target.border_segments_complex_superellipse,
|
||||
+ VertexArrayKind::Border,
|
||||
+ &BatchTextures::empty(),
|
||||
+ stats,
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
self.set_blend(false, FramebufferKind::Other);
|
||||
}
|
||||
|
||||
// Draw any line decorations for this target.
|
||||
if !target.line_decorations.is_empty() {
|
||||
diff --git a/gfx/wr/webrender/src/renderer/shade.rs b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
--- a/gfx/wr/webrender/src/renderer/shade.rs
|
||||
+++ b/gfx/wr/webrender/src/renderer/shade.rs
|
||||
@@ -413,10 +413,12 @@
|
||||
// draw intermediate results to cache targets. The results
|
||||
// of these shaders are then used by the primitive shaders.
|
||||
cs_blur_rgba8: ShaderHandle,
|
||||
cs_border_segment: ShaderHandle,
|
||||
cs_border_solid: ShaderHandle,
|
||||
+ cs_border_segment_superellipse: ShaderHandle,
|
||||
+ cs_border_solid_superellipse: ShaderHandle,
|
||||
cs_scale: Vec<Option<ShaderHandle>>,
|
||||
cs_line_decoration: ShaderHandle,
|
||||
cs_svg_filter_node: ShaderHandle,
|
||||
|
||||
// The are "primitive shaders". These shaders draw and blend
|
||||
@@ -774,19 +776,35 @@
|
||||
"cs_border_solid",
|
||||
&[],
|
||||
&shader_list,
|
||||
)?;
|
||||
|
||||
+ let cs_border_segment_superellipse = loader.create_shader(
|
||||
+ ShaderKind::Cache(VertexArrayKind::Border),
|
||||
+ "cs_border_segment",
|
||||
+ &[SUPERELLIPSE_FEATURE],
|
||||
+ &shader_list,
|
||||
+ )?;
|
||||
+
|
||||
+ let cs_border_solid_superellipse = loader.create_shader(
|
||||
+ ShaderKind::Cache(VertexArrayKind::Border),
|
||||
+ "cs_border_solid",
|
||||
+ &[SUPERELLIPSE_FEATURE],
|
||||
+ &shader_list,
|
||||
+ )?;
|
||||
+
|
||||
let composite = CompositorShaders::new(device, gl_type, &mut loader)?;
|
||||
|
||||
Ok(Shaders {
|
||||
loader,
|
||||
|
||||
cs_blur_rgba8,
|
||||
cs_border_segment,
|
||||
- cs_line_decoration,
|
||||
cs_border_solid,
|
||||
+ cs_border_segment_superellipse,
|
||||
+ cs_border_solid_superellipse,
|
||||
+ cs_line_decoration,
|
||||
cs_scale,
|
||||
cs_svg_filter_node,
|
||||
ps_text_run,
|
||||
ps_text_run_dual_source,
|
||||
ps_quad_textured,
|
||||
@@ -979,10 +997,12 @@
|
||||
}
|
||||
|
||||
pub fn cs_blur_rgba8(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_blur_rgba8) }
|
||||
pub fn cs_border_segment(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_border_segment) }
|
||||
pub fn cs_border_solid(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_border_solid) }
|
||||
+ pub fn cs_border_segment_superellipse(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_border_segment_superellipse) }
|
||||
+ pub fn cs_border_solid_superellipse(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_border_solid_superellipse) }
|
||||
pub fn cs_line_decoration(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_line_decoration) }
|
||||
pub fn cs_svg_filter_node(&mut self) -> &mut LazilyCompiledShader { self.loader.get(self.cs_svg_filter_node) }
|
||||
pub fn ps_quad_textured(&mut self) -> &mut LazilyCompiledShader {
|
||||
self.loader.get(self.ps_quad_textured)
|
||||
}
|
||||
diff --git a/gfx/wr/webrender_build/src/shader_features.rs b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
--- a/gfx/wr/webrender_build/src/shader_features.rs
|
||||
+++ b/gfx/wr/webrender_build/src/shader_features.rs
|
||||
@@ -69,17 +69,22 @@
|
||||
|
||||
shaders.insert("ps_quad_mask", vec![String::new(), "FAST_PATH".to_string(), "SUPERELLIPSE".to_string()]);
|
||||
|
||||
for name in &[
|
||||
"cs_line_decoration",
|
||||
- "cs_border_segment",
|
||||
- "cs_border_solid",
|
||||
"cs_svg_filter_node",
|
||||
] {
|
||||
shaders.insert(name, vec![String::new()]);
|
||||
}
|
||||
|
||||
+ for name in &[
|
||||
+ "cs_border_segment",
|
||||
+ "cs_border_solid",
|
||||
+ ] {
|
||||
+ shaders.insert(name, vec![String::new(), "SUPERELLIPSE".to_string()]);
|
||||
+ }
|
||||
+
|
||||
let mut base_prim_features = FeatureList::new();
|
||||
|
||||
let mut texture_types = vec!["TEXTURE_2D"];
|
||||
if flags.contains(ShaderFeatureFlags::GL) {
|
||||
texture_types.push("TEXTURE_RECT");
|
||||
|
||||
15
src/external-patches/firefox/bug_2063169/D320211.patch
Normal file
15
src/external-patches/firefox/bug_2063169/D320211.patch
Normal file
@@ -0,0 +1,15 @@
|
||||
diff --git a/devtools/client/responsive/test/browser/browser.toml b/devtools/client/responsive/test/browser/browser.toml
|
||||
--- a/devtools/client/responsive/test/browser/browser.toml
|
||||
+++ b/devtools/client/responsive/test/browser/browser.toml
|
||||
@@ -275,7 +275,10 @@
|
||||
skip-if = [
|
||||
"os == 'win' && os_version == '11.26100' && arch == 'x86_64' && asan", # Bug 2016837
|
||||
]
|
||||
|
||||
["browser_window_sizing.js"]
|
||||
+skip-if = [
|
||||
+ "os == 'win' && opt && standalone", # Bug 2063169
|
||||
+]
|
||||
|
||||
["browser_zoom.js"]
|
||||
|
||||
34
src/external-patches/firefox/bug_2063169/D320568.patch
Normal file
34
src/external-patches/firefox/bug_2063169/D320568.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp
|
||||
--- a/layout/painting/nsDisplayList.cpp
|
||||
+++ b/layout/painting/nsDisplayList.cpp
|
||||
@@ -4606,12 +4606,12 @@
|
||||
wr::LayoutRect deviceClipRect = wr::ToLayoutRect(clipRect);
|
||||
|
||||
nscoord spread = shadow.spread.ToAppUnits();
|
||||
float spreadRadius = float(spread) / float(appUnitsPerDevPixel);
|
||||
|
||||
- wr::BorderRadius borderRadius{};
|
||||
- wr::BorderRadius shadowRadius{};
|
||||
+ wr::BorderRadius borderRadius = wr::EmptyBorderRadius();
|
||||
+ wr::BorderRadius shadowRadius = wr::EmptyBorderRadius();
|
||||
if (hasBorderRadius) {
|
||||
borderRadius = wr::ToBorderRadius(borderRadii);
|
||||
if (spreadRadius) {
|
||||
auto shadowRadii = borderRadii;
|
||||
shadowRadii.AdjustOutwards(
|
||||
@@ -4727,12 +4727,12 @@
|
||||
float(shadow.base.blur.ToAppUnits()) / float(appUnitsPerDevPixel);
|
||||
|
||||
nscoord spread = shadow.spread.ToAppUnits();
|
||||
float spreadRadius = spread / float(appUnitsPerDevPixel);
|
||||
|
||||
- wr::BorderRadius borderRadius{};
|
||||
- wr::BorderRadius shadowRadius{};
|
||||
+ wr::BorderRadius borderRadius = wr::EmptyBorderRadius();
|
||||
+ wr::BorderRadius shadowRadius = wr::EmptyBorderRadius();
|
||||
if (hasBorderRadius) {
|
||||
borderRadius = wr::ToBorderRadius(innerRadii);
|
||||
if (spreadRadius) {
|
||||
RectCornerRadii shadowRadii = innerRadii;
|
||||
shadowRadii.AdjustInwards(
|
||||
|
||||
53
src/external-patches/firefox/bug_2063169/D321282.patch
Normal file
53
src/external-patches/firefox/bug_2063169/D321282.patch
Normal file
@@ -0,0 +1,53 @@
|
||||
diff --git a/gfx/wr/webrender/res/ps_quad_mask.glsl b/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
--- a/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
+++ b/gfx/wr/webrender/res/ps_quad_mask.glsl
|
||||
@@ -318,12 +318,30 @@
|
||||
#endif
|
||||
|
||||
vec4 clip_dist =
|
||||
mix(clip_rect, clip_rect.zwxy, lessThan(local_step, vec2(0.0)).xyxy)
|
||||
- local_pos0.xyxy;
|
||||
+
|
||||
+ // Half-width, in local units, of the band around an edge over which
|
||||
+ // distance_aa() produces partial coverage.
|
||||
+ float aa_band = 0.5 * recip(aa_range);
|
||||
+ // An axis the span does not step along has the same distance to its two
|
||||
+ // edges for every pixel of the span, so the inside/outside test below
|
||||
+ // cannot resolve an edge that runs parallel to the span and coverage ends
|
||||
+ // up quantized to whole spans. Grow the rect by the AA band so that a span
|
||||
+ // landing inside the band counts as inside, which leaves the corner
|
||||
+ // selection below unchanged, and remember that the span is only partially
|
||||
+ // covered so the opaque run can be dropped further down.
|
||||
+ // `inset` is the distance from the span to the nearer of an axis' two
|
||||
+ // edges, positive when the span is between them.
|
||||
+ vec2 inset = min(-clip_dist.xy, clip_dist.zw);
|
||||
+ bvec2 flat_axis = equal(local_step, vec2(0.0));
|
||||
+ bvec2 partial = lessThan(inset, vec2(aa_band));
|
||||
+ bool aa_span = (flat_axis.x && partial.x) || (flat_axis.y && partial.y);
|
||||
+
|
||||
clip_dist =
|
||||
- mix(1.0e6 * step(0.0, clip_dist),
|
||||
+ mix(1.0e6 * step(0.0, clip_dist - vec4(aa_band, aa_band, -aa_band, -aa_band)),
|
||||
clip_dist * recip(local_step).xyxy,
|
||||
notEqual(local_step, vec2(0.0)).xyxy);
|
||||
|
||||
float opaque_start = max(clip_dist.x, clip_dist.y);
|
||||
float opaque_end = min(clip_dist.z, clip_dist.w);
|
||||
@@ -404,10 +422,16 @@
|
||||
|
||||
aa_margin = max(aa_margin - max(aa_start - aa_end, 0.0), 0.0);
|
||||
aa_start -= aa_margin;
|
||||
aa_end += aa_margin;
|
||||
|
||||
+ if (aa_span) {
|
||||
+ // No pixel of the span is fully covered, so collapse the opaque run and
|
||||
+ // let the anti-aliased runs on either side of it cover the whole span.
|
||||
+ opaque_end = min(opaque_end, opaque_start);
|
||||
+ }
|
||||
+
|
||||
ivec4 steps = ivec4(clamp(
|
||||
swgl_SpanLength -
|
||||
swgl_StepSize *
|
||||
vec4(floor(aa_start), ceil(opaque_start), floor(opaque_end), ceil(aa_end)),
|
||||
0.0, swgl_SpanLength));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,14 @@
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"path": "firefox/css_corner_shape_rendering.patch"
|
||||
// Sorts before bug_2063169/ on purpose: D319869 builds on the border
|
||||
// shader hunks in here, and surfer applies patches in path order.
|
||||
"path": "firefox/bug_2047627_corner_shape_borders.patch"
|
||||
},
|
||||
{
|
||||
"type": "phabricator",
|
||||
"ids": ["D319577", "D319796", "D319869", "D320211", "D320568", "D321282"],
|
||||
"name": "Bug 2063169"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
:root:not([zen-no-padding="true"]) &:not(.zen-glance-overlay) {
|
||||
border-radius: var(--zen-native-inner-radius);
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
@media not (-moz-pref("zen.theme.squircle-browser-view")) {
|
||||
/* stylelint-disable-next-line property-no-unknown */
|
||||
corner-shape: round;
|
||||
border-radius: calc(var(--zen-native-inner-radius) / var(--zen-squircle-value));
|
||||
}
|
||||
}
|
||||
|
||||
& browser[type="content"] {
|
||||
|
||||
@@ -105,6 +105,11 @@
|
||||
.browserSidebarContainer.zen-glance-background,
|
||||
.browserSidebarContainer.zen-glance-overlay .browserContainer:not([fade-out="true"]) {
|
||||
border-radius: var(--zen-native-inner-radius);
|
||||
@media not (-moz-pref("zen.theme.squircle-browser-view")) {
|
||||
/* stylelint-disable-next-line property-no-unknown */
|
||||
corner-shape: round;
|
||||
border-radius: calc(var(--zen-native-inner-radius) / var(--zen-squircle-value));
|
||||
}
|
||||
}
|
||||
|
||||
.browserSidebarContainer.zen-glance-overlay {
|
||||
@@ -144,6 +149,11 @@
|
||||
border-radius: var(--zen-native-inner-radius);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--zen-big-shadow);
|
||||
@media not (-moz-pref("zen.theme.squircle-browser-view")) {
|
||||
/* stylelint-disable-next-line property-no-unknown */
|
||||
corner-shape: round;
|
||||
border-radius: calc(var(--zen-native-inner-radius) / var(--zen-squircle-value));
|
||||
}
|
||||
}
|
||||
|
||||
& browser {
|
||||
|
||||
@@ -110,7 +110,7 @@ class nsZenWorkspaceIcons extends MozXULElement {
|
||||
button.setAttribute("zen-workspace-id", workspace.uuid);
|
||||
button.setAttribute("context", "zenWorkspaceMoreActions");
|
||||
const icon = document.createXULElement("label");
|
||||
icon.setAttribute("class", "zen-workspace-icon");
|
||||
icon.setAttribute("class", "zen-workspace-icon no-squircles");
|
||||
const isSvgIcon = workspace.icon && workspace.icon.endsWith(".svg");
|
||||
if (gZenWorkspaces.workspaceHasIcon(workspace)) {
|
||||
if (isSvgIcon) {
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
& toolbarbutton {
|
||||
margin: 0;
|
||||
max-width: 28px;
|
||||
max-width: 30px;
|
||||
border-radius: var(--toolbarbutton-border-radius);
|
||||
height: 28px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 0 !important;
|
||||
@@ -58,8 +58,8 @@
|
||||
}
|
||||
|
||||
&[no-icon='true'] {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: light-dark(rgba(0, 0, 0, 0.4), rgba(255, 255, 255, 0.4));
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@@ -1059,7 +1059,6 @@
|
||||
|
||||
#tabs-newtab-button {
|
||||
display: none;
|
||||
font-weight: 500;
|
||||
-moz-user-focus: ignore !important;
|
||||
}
|
||||
|
||||
@@ -1342,7 +1341,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#tabs-newtab-button:not([in-urlbar="true"]) label,
|
||||
#tabs-newtab-button:not([in-urlbar="true"]),
|
||||
.zen-current-workspace-indicator-name {
|
||||
color: color-mix(in srgb, currentColor 70%, transparent);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user