Skip to content

Commit

Permalink
Bug 1907481 - Add support for patterns that have texture input source…
Browse files Browse the repository at this point in the history
…s r=gfx-reviewers,lsalzman

Not currently used in this patch, but will be by the upcoming
box-shadow patches.

Differential Revision: https://phabricator.services.mozilla.com/D216365
  • Loading branch information
Glenn Watson authored and web-flow committed Jul 21, 2024
1 parent 180390b commit a6d2963
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 65 deletions.
11 changes: 11 additions & 0 deletions webrender/res/gpu_buffer.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ vec4[4] fetch_from_gpu_buffer_4f(HIGHP_FS_ADDRESS int address) {
);
}

vec4[5] fetch_from_gpu_buffer_5f(HIGHP_FS_ADDRESS int address) {
ivec2 uv = get_gpu_buffer_uv(address);
return vec4[5](
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(0, 0)),
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(1, 0)),
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(2, 0)),
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(3, 0)),
TEXEL_FETCH(sGpuBufferF, uv, 0, ivec2(4, 0))
);
}

ivec4 fetch_from_gpu_buffer_1i(HIGHP_FS_ADDRESS int address) {
ivec2 uv = get_gpu_buffer_uv(address);
return texelFetch(sGpuBufferI, uv, 0);
Expand Down
12 changes: 7 additions & 5 deletions webrender/res/ps_quad.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,15 @@ struct PrimitiveInfo {
struct QuadPrimitive {
RectWithEndpoint bounds;
RectWithEndpoint clip;
RectWithEndpoint uv_rect;
vec4 pattern_scale_offset;
vec4 color;
};

QuadSegment fetch_segment(int base, int index) {
QuadSegment seg;

vec4 texels[2] = fetch_from_gpu_buffer_2f(base + 4 + index * 2);
vec4 texels[2] = fetch_from_gpu_buffer_2f(base + 5 + index * 2);

seg.rect = RectWithEndpoint(texels[0].xy, texels[0].zw);
seg.uv_rect = RectWithEndpoint(texels[1].xy, texels[1].zw);
Expand All @@ -114,12 +115,13 @@ QuadSegment fetch_segment(int base, int index) {
QuadPrimitive fetch_primitive(int index) {
QuadPrimitive prim;

vec4 texels[4] = fetch_from_gpu_buffer_4f(index);
vec4 texels[5] = fetch_from_gpu_buffer_5f(index);

prim.bounds = RectWithEndpoint(texels[0].xy, texels[0].zw);
prim.clip = RectWithEndpoint(texels[1].xy, texels[1].zw);
prim.pattern_scale_offset = texels[2];
prim.color = texels[3];
prim.uv_rect = RectWithEndpoint(texels[2].xy, texels[2].zw);
prim.pattern_scale_offset = texels[3];
prim.color = texels[4];

return prim;
}
Expand Down Expand Up @@ -246,7 +248,7 @@ PrimitiveInfo quad_primive_info(void) {
QuadSegment seg;
if (qi.segment_index == INVALID_SEGMENT_INDEX) {
seg.rect = prim.bounds;
seg.uv_rect = RectWithEndpoint(vec2(0.0), vec2(0.0));
seg.uv_rect = prim.uv_rect;
} else {
seg = fetch_segment(qi.prim_address_f, qi.segment_index);
}
Expand Down
20 changes: 19 additions & 1 deletion webrender/src/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use api::ColorF;

use crate::{renderer::GpuBufferBuilder, scene::SceneProperties};
use crate::{render_task_graph::RenderTaskId, renderer::GpuBufferBuilder, scene::SceneProperties};

#[repr(u32)]
#[cfg_attr(feature = "capture", derive(Serialize))]
Expand Down Expand Up @@ -42,6 +42,21 @@ impl Default for PatternShaderInput {
}
}

#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct PatternTextureInput {
pub task_id: RenderTaskId,
}

impl Default for PatternTextureInput {
fn default() -> Self {
PatternTextureInput {
task_id: RenderTaskId::INVALID,
}
}
}

pub struct PatternBuilderContext<'a> {
pub scene_properties: &'a SceneProperties,
}
Expand All @@ -62,6 +77,7 @@ pub trait PatternBuilder {
pub struct Pattern {
pub kind: PatternKind,
pub shader_input: PatternShaderInput,
pub texture_input: PatternTextureInput,
pub base_color: ColorF,
pub is_opaque: bool,
}
Expand All @@ -71,6 +87,7 @@ impl Pattern {
Pattern {
kind: PatternKind::ColorOrTexture,
shader_input: PatternShaderInput::default(),
texture_input: PatternTextureInput::default(),
base_color: color,
is_opaque: color.a >= 1.0,
}
Expand All @@ -81,6 +98,7 @@ impl Pattern {
Pattern {
kind: PatternKind::ColorOrTexture,
shader_input: PatternShaderInput::default(),
texture_input: PatternTextureInput::default(),
base_color: ColorF::BLACK,
is_opaque: false,
}
Expand Down
7 changes: 5 additions & 2 deletions webrender/src/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! TODO: document this!

use api::{PremultipliedColorF, PropertyBinding};
use api::{ColorF, PropertyBinding};
use api::{BoxShadowClipMode, BorderStyle, ClipMode};
use api::units::*;
use euclid::Scale;
Expand All @@ -16,6 +16,7 @@ use crate::command_buffer::{PrimitiveCommand, CommandBufferIndex};
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::spatial_tree::{SpatialNodeIndex, SpatialTree};
use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainInstance, ClipItemKind};
use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureContext, PictureState};
Expand Down Expand Up @@ -952,11 +953,13 @@ fn prepare_interned_prim_for_render(
.clipped_local_rect
.cast_unit();

let pattern = Pattern::color(ColorF::WHITE);

let prim_address_f = quad::write_prim_blocks(
&mut frame_state.frame_gpu_data.f32,
prim_local_rect,
prim_instance.vis.clip_chain.local_clip_rect,
PremultipliedColorF::WHITE,
&pattern,
&[],
ScaleOffset::identity(),
);
Expand Down
3 changes: 2 additions & 1 deletion webrender/src/prim_store/gradient/conic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use euclid::vec2;
use api::{ColorF, ExtendMode, GradientStop, PremultipliedColorF};
use api::units::*;
use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput};
use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput, PatternTextureInput};
use crate::scene_building::IsVisible;
use crate::frame_builder::FrameBuildingState;
use crate::intern::{Internable, InternDebug, Handle as InternHandle};
Expand Down Expand Up @@ -454,6 +454,7 @@ pub fn conic_gradient_pattern(
gradient_address.as_int(),
stops_address.as_int(),
),
texture_input: PatternTextureInput::default(),
base_color: ColorF::WHITE,
is_opaque,
}
Expand Down
3 changes: 2 additions & 1 deletion webrender/src/prim_store/gradient/radial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use euclid::{vec2, size2};
use api::{ColorF, ColorU, ExtendMode, GradientStop, PremultipliedColorF};
use api::units::*;
use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput};
use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput, PatternTextureInput};
use crate::scene_building::IsVisible;
use crate::frame_builder::FrameBuildingState;
use crate::intern::{Internable, InternDebug, Handle as InternHandle};
Expand Down Expand Up @@ -587,6 +587,7 @@ pub fn radial_gradient_pattern(
gradient_address.as_int(),
stops_address.as_int(),
),
texture_input: PatternTextureInput::default(),
base_color: ColorF::WHITE,
is_opaque,
}
Expand Down
51 changes: 36 additions & 15 deletions webrender/src/quad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{units::*, ClipMode, PremultipliedColorF};
use api::{units::*, ClipMode};
use euclid::point2;

use crate::batch::{BatchKey, BatchKind, BatchTextures};
Expand Down Expand Up @@ -143,7 +143,7 @@ pub fn prepare_quad(
&mut frame_state.frame_gpu_data.f32,
*local_rect,
clip_chain.local_clip_rect,
pattern.base_color.premultiplied(),
&pattern,
&[],
ScaleOffset::identity(),
);
Expand All @@ -164,13 +164,33 @@ pub fn prepare_quad(
prim_spatial_node_index,
targets,
);

// If the pattern samples from a texture, add it as a dependency
// of the surface we're drawing directly on to.
if pattern.texture_input.task_id != RenderTaskId::INVALID {
frame_state
.surface_builder
.add_child_render_task(pattern.texture_input.task_id, frame_state.rg_builder);
}

return;
}

let surface = &mut frame_state.surfaces[pic_context.surface_index.0];
let Some(clipped_surface_rect) = surface.get_surface_rect(
&clip_chain.pic_coverage_rect, frame_context.spatial_tree
) else {
// In the rare case of getting to here with a prim that wasn't culled
// earlier, but that gets clipped here (e.g. float issues), we need
// to add any render task created by the pattern as a dependency to
// the surface so it gets freed when building the graph.
// TODO(gw): We should maybe have a proper way to cancel render tasks...
if pattern.texture_input.task_id != RenderTaskId::INVALID {
frame_state
.surface_builder
.add_child_render_task(pattern.texture_input.task_id, frame_state.rg_builder);
}

return;
};

Expand Down Expand Up @@ -707,9 +727,16 @@ fn add_render_task_with_mask(
aa_flags,
quad_flags,
needs_scissor_rect,
pattern.texture_input.task_id,
),
));

// If the pattern samples from a texture, add it as a dependency
// of the indirect render task that relies on it.
if pattern.texture_input.task_id != RenderTaskId::INVALID {
frame_state.rg_builder.add_dependency(task_id, pattern.texture_input.task_id);
}

if clips_range.count > 0 {
let masks = MaskSubPass {
clip_node_range: clips_range,
Expand Down Expand Up @@ -743,7 +770,7 @@ fn add_pattern_prim(
&mut frame_state.frame_gpu_data.f32,
rect,
clip_rect,
pattern.base_color.premultiplied(),
pattern,
segments,
pattern_transform,
);
Expand Down Expand Up @@ -790,7 +817,7 @@ fn add_composite_prim(
// in the quad primitive). However, passing opaque white
// here causes glitches with Adreno GPUs on Windows specifically
// (See bug 1897444).
pattern.base_color.premultiplied(),
pattern,
segments,
ScaleOffset::identity(),
);
Expand Down Expand Up @@ -823,27 +850,21 @@ pub fn write_prim_blocks(
builder: &mut GpuBufferBuilderF,
prim_rect: LayoutRect,
clip_rect: LayoutRect,
color: PremultipliedColorF,
pattern: &Pattern,
segments: &[QuadSegment],
scale_offset: ScaleOffset,
) -> GpuBufferAddress {
let mut writer = builder.write_blocks(4 + segments.len() * 2);
let mut writer = builder.write_blocks(5 + segments.len() * 2);

writer.push_one(prim_rect);
writer.push_one(clip_rect);
writer.push_render_task(pattern.texture_input.task_id);
writer.push_one(scale_offset);
writer.push_one(color);
writer.push_one(pattern.base_color.premultiplied());

for segment in segments {
writer.push_one(segment.rect);
match segment.task_id {
RenderTaskId::INVALID => {
writer.push_one([0.0; 4]);
}
task_id => {
writer.push_render_task(task_id);
}
}
writer.push_render_task(segment.task_id)
}

writer.finish()
Expand Down
Loading

0 comments on commit a6d2963

Please sign in to comment.