tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 1acc4435576ca5ed679d6277403da97b7d5bed98
parent 86b60597ed89fdd437f97225d0c7a16216db3c41
Author: Nicolas Silva <nical@fastmail.com>
Date:   Wed, 19 Nov 2025 22:17:35 +0000

Bug 2000393 - Add LinearGradientBrushData. r=gw

Also lie a bit less about the coordinate space of the gradient parameters (which are actually layout coordinates despite previously being stored as device coordinates).

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

Diffstat:
Mgfx/wr/webrender/res/brush_linear_gradient.glsl | 8++++----
Mgfx/wr/webrender/src/gpu_types.rs | 28+++++++++++++++++++++++++++-
Mgfx/wr/webrender/src/prepare.rs | 27++++++++++-----------------
Mgfx/wr/webrender/src/prim_store/gradient/linear.rs | 40++++++++++++++++++----------------------
4 files changed, 59 insertions(+), 44 deletions(-)

diff --git a/gfx/wr/webrender/res/brush_linear_gradient.glsl b/gfx/wr/webrender/res/brush_linear_gradient.glsl @@ -13,15 +13,15 @@ flat varying mediump vec2 v_scale_dir; #ifdef WR_VERTEX_SHADER -struct Gradient { +struct LinearGradientBrushData { vec4 start_end_point; int extend_mode; vec2 stretch_size; }; -Gradient fetch_gradient(int address) { +LinearGradientBrushData fetch_gradient(int address) { vec4 data[2] = fetch_from_gpu_buffer_2f(address); - return Gradient( + return LinearGradientBrushData( data[0], int(data[1].x), data[1].yz @@ -40,7 +40,7 @@ void brush_vs( int brush_flags, vec4 texel_rect ) { - Gradient gradient = fetch_gradient(prim_address); + LinearGradientBrushData gradient = fetch_gradient(prim_address); write_gradient_vertex( vi, diff --git a/gfx/wr/webrender/src/gpu_types.rs b/gfx/wr/webrender/src/gpu_types.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use api::{AlphaType, PremultipliedColorF, YuvFormat, YuvRangedColorSpace}; +use api::{AlphaType, ExtendMode, PremultipliedColorF, YuvFormat, YuvRangedColorSpace}; use api::units::*; use euclid::HomogeneousVector; use crate::composite::{CompositeFeatures, CompositorClip}; @@ -710,6 +710,32 @@ impl GpuBufferDataF for QuadSegment { } } +/// Matches LinearGradientBrushData in brush_linear_gradient.glsl +pub struct LinearGradientBrushData { + pub start: LayoutPoint, + pub end: LayoutPoint, + pub extend_mode: ExtendMode, + pub stretch_size: LayoutSize, +} + +impl GpuBufferDataF for LinearGradientBrushData { + const NUM_BLOCKS: usize = 2; + fn write(&self, writer: &mut GpuBufferWriterF) { + writer.push_one([ + self.start.x, + self.start.y, + self.end.x, + self.end.y, + ]); + writer.push_one([ + pack_as_float(self.extend_mode as u32), + self.stretch_size.width, + self.stretch_size.height, + 0.0, + ]); + } +} + #[derive(Copy, Debug, Clone, PartialEq)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] diff --git a/gfx/wr/webrender/src/prepare.rs b/gfx/wr/webrender/src/prepare.rs @@ -17,11 +17,11 @@ use crate::image_tiling::{self, Repetition}; use crate::border::{get_max_scale_for_border, build_border_instances}; use crate::clip::{ClipStore, ClipNodeRange}; use crate::pattern::Pattern; -use crate::renderer::{GpuBufferAddress, GpuBufferBuilderF, GpuBufferWriterF}; +use crate::renderer::{GpuBufferAddress, GpuBufferBuilderF, GpuBufferWriterF, GpuBufferDataF}; use crate::spatial_tree::{SpatialNodeIndex, SpatialTree}; use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainInstance, ClipItemKind}; use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState}; -use crate::gpu_types::BrushFlags; +use crate::gpu_types::{BrushFlags, LinearGradientBrushData}; use crate::internal_types::{FastHashMap, PlaneSplitAnchor, Filter}; use crate::picture::{ClusterFlags, PictureCompositeMode, PicturePrimitive, SliceId}; use crate::picture::{PrimitiveList, PrimitiveCluster, SurfaceIndex, TileCacheInstance, SubpixelMode, Picture3DContext}; @@ -35,7 +35,7 @@ use crate::render_task_cache::RenderTaskCacheKeyKind; use crate::render_task_cache::{RenderTaskCacheKey, to_cache_size, RenderTaskParent}; use crate::render_task::{EmptyTask, MaskSubPass, RenderTask, RenderTaskKind, SubPass}; use crate::segment::SegmentBuilder; -use crate::util::{clamp_to_scale_factor, pack_as_float, ScaleOffset}; +use crate::util::{clamp_to_scale_factor, ScaleOffset}; use crate::visibility::{compute_conservative_visible_rect, PrimitiveVisibility, VisibilityState}; @@ -786,20 +786,13 @@ fn prepare_interned_prim_for_render( &mut scratch.gradient_tiles, &frame_context.spatial_tree, Some(&mut |_, gpu_buffer| { - let mut writer = gpu_buffer.write_blocks(2); - writer.push_one([ - prim_data.start_point.x, - prim_data.start_point.y, - prim_data.end_point.x, - prim_data.end_point.y, - ]); - writer.push_one([ - pack_as_float(prim_data.extend_mode as u32), - prim_data.stretch_size.width, - prim_data.stretch_size.height, - 0.0, - ]); - + let mut writer = gpu_buffer.write_blocks(LinearGradientBrushData::NUM_BLOCKS); + writer.push(&LinearGradientBrushData { + start: prim_data.start_point, + end: prim_data.end_point, + extend_mode: prim_data.extend_mode, + stretch_size: prim_data.stretch_size, + }); writer.finish() }), ); diff --git a/gfx/wr/webrender/src/prim_store/gradient/linear.rs b/gfx/wr/webrender/src/prim_store/gradient/linear.rs @@ -12,7 +12,7 @@ use euclid::approxeq::ApproxEq; use euclid::{point2, vec2, size2}; use api::{ExtendMode, GradientStop, LineOrientation, PremultipliedColorF, ColorF, ColorU}; use api::units::*; -use crate::gpu_types::ImageBrushPrimitiveData; +use crate::gpu_types::{ImageBrushPrimitiveData, LinearGradientBrushData}; use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput, PatternTextureInput}; use crate::prim_store::gradient::{gpu_gradient_stops_blocks, write_gpu_gradient_stops_tree, write_gpu_gradient_stops_linear, GradientKind}; use crate::scene_building::IsVisible; @@ -29,7 +29,6 @@ use crate::render_task_graph::RenderTaskId; use crate::render_task_cache::{RenderTaskCacheKeyKind, RenderTaskCacheKey, RenderTaskParent}; use crate::renderer::{GpuBufferAddress, GpuBufferBuilder}; use crate::segment::EdgeAaSegmentMask; -use crate::util::pack_as_float; use super::{stops_and_min_alpha, GradientStopKey, GradientGpuBlockBuilder, apply_gradient_local_clip}; use std::ops::{Deref, DerefMut}; use std::mem::swap; @@ -85,8 +84,8 @@ impl InternDebug for LinearGradientKey {} pub struct LinearGradientTemplate { pub common: PrimTemplateCommonData, pub extend_mode: ExtendMode, - pub start_point: DevicePoint, - pub end_point: DevicePoint, + pub start_point: LayoutPoint, + pub end_point: LayoutPoint, pub task_size: DeviceIntSize, pub scale: DeviceVector2D, pub stretch_size: LayoutSize, @@ -398,8 +397,8 @@ impl From<LinearGradientKey> for LinearGradientTemplate { // should be drawn in. let stops_opacity = PrimitiveOpacity::from_alpha(min_alpha); - let start_point = DevicePoint::new(item.start_point.x, item.start_point.y); - let end_point = DevicePoint::new(item.end_point.x, item.end_point.y); + let start_point = LayoutPoint::new(item.start_point.x, item.start_point.y); + let end_point = LayoutPoint::new(item.end_point.x, item.end_point.y); let tile_spacing: LayoutSize = item.tile_spacing.into(); let stretch_size: LayoutSize = item.stretch_size.into(); let mut task_size: DeviceSize = stretch_size.cast_unit(); @@ -506,18 +505,12 @@ impl LinearGradientTemplate { }); } else { // We are using the gradient brush. - writer.push_one([ - self.start_point.x, - self.start_point.y, - self.end_point.x, - self.end_point.y, - ]); - writer.push_one([ - pack_as_float(self.extend_mode as u32), - self.stretch_size.width, - self.stretch_size.height, - 0.0, - ]); + writer.push(&LinearGradientBrushData { + start: self.start_point, + end: self.end_point, + extend_mode: self.extend_mode, + stretch_size: self.stretch_size, + }); } // write_segment_gpu_blocks @@ -598,8 +591,11 @@ impl LinearGradientTemplate { rg_builder.add().init(RenderTask::new_dynamic( self.task_size, RenderTaskKind::LinearGradient(LinearGradientTask { - start: self.start_point, - end: self.end_point, + // Cached brush gradients are rasteried with 1 layout + // pixel = 1 device pixel (regardless of potential + // scaling factors). + start: self.start_point.cast_unit(), + end: self.end_point.cast_unit(), scale: self.scale, extend_mode: self.extend_mode, stops: stops.unwrap(), @@ -781,8 +777,8 @@ pub struct LinearGradientCacheKey { } pub fn linear_gradient_pattern( - start: DevicePoint, - end: DevicePoint, + start: LayoutPoint, + end: LayoutPoint, extend_mode: ExtendMode, stops: &[GradientStop], is_software: bool,