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 #3857

Merged
merged 1 commit into from Feb 13, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Bug 1614890 - Implement conic-gradient for WebRender graphics backend…

  • Loading branch information
nt1m authored and moz-gfx committed Feb 13, 2020
commit c980ba18a3c99ae3795825f1e3617bc70fc7db27
@@ -89,6 +89,7 @@ FWD_DECLARE_VS_FUNCTION(blend_brush_vs)
FWD_DECLARE_VS_FUNCTION(mix_blend_brush_vs)
FWD_DECLARE_VS_FUNCTION(linear_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(radial_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(conic_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(yuv_brush_vs)
FWD_DECLARE_VS_FUNCTION(opacity_brush_vs)

@@ -258,6 +259,7 @@ Fragment blend_brush_fs();
Fragment mix_blend_brush_fs();
Fragment linear_gradient_brush_fs();
Fragment radial_gradient_brush_fs();
Fragment conic_gradient_brush_fs();
Fragment yuv_brush_fs();
Fragment opacity_brush_fs();
Fragment multi_brush_fs(int brush_kind);
@@ -0,0 +1,140 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

#define VECS_PER_CONIC_GRADIENT_BRUSH 2
#define VECS_PER_SPECIFIC_BRUSH VECS_PER_CONIC_GRADIENT_BRUSH

#define WR_BRUSH_VS_FUNCTION conic_gradient_brush_vs
#define WR_BRUSH_FS_FUNCTION conic_gradient_brush_fs

#include shared,prim_shared,brush

#define V_GRADIENT_ADDRESS flat_varying_highp_int_address_0

#define V_CENTER flat_varying_vec4_0.xy
#define V_ANGLE flat_varying_vec4_0.z

// Size of the gradient pattern's rectangle, used to compute horizontal and vertical
// repetitions. Not to be confused with another kind of repetition of the pattern
// which happens along the gradient stops.
#define V_REPEATED_SIZE flat_varying_vec4_1.xy
// Repetition along the gradient stops.
#define V_GRADIENT_REPEAT flat_varying_vec4_1.z

#define V_POS varying_vec4_0.zw

#ifdef WR_FEATURE_ALPHA_PASS
#define V_LOCAL_POS varying_vec4_0.xy
#define V_TILE_REPEAT flat_varying_vec4_2.xy
#endif

#define PI 3.1415926538

#ifdef WR_VERTEX_SHADER

struct ConicGradient {
vec2 center_point;
float angle;
int extend_mode;
vec2 stretch_size;
};

ConicGradient fetch_gradient(int address) {
vec4 data[2] = fetch_from_gpu_cache_2(address);
return ConicGradient(
data[0].xy,
float(data[0].z),
int(data[1].x),
data[1].yz
);
}

void conic_gradient_brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize local_rect,
RectWithSize segment_rect,
ivec4 prim_user_data,
int specific_resource_address,
mat4 transform,
PictureTask pic_task,
int brush_flags,
vec4 texel_rect
) {
ConicGradient gradient = fetch_gradient(prim_address);

if ((brush_flags & BRUSH_FLAG_SEGMENT_RELATIVE) != 0) {
V_POS = (vi.local_pos - segment_rect.p0) / segment_rect.size;
V_POS = V_POS * (texel_rect.zw - texel_rect.xy) + texel_rect.xy;
V_POS = V_POS * local_rect.size;
} else {
V_POS = vi.local_pos - local_rect.p0;
}

V_CENTER = gradient.center_point;
V_ANGLE = gradient.angle;

vec2 tile_repeat = local_rect.size / gradient.stretch_size;
V_REPEATED_SIZE = gradient.stretch_size;

V_GRADIENT_ADDRESS = prim_user_data.x;

// Whether to repeat the gradient along the line instead of clamping.
V_GRADIENT_REPEAT = float(gradient.extend_mode != EXTEND_MODE_CLAMP);

#ifdef WR_FEATURE_ALPHA_PASS
V_TILE_REPEAT = tile_repeat;
V_LOCAL_POS = vi.local_pos;
#endif
}
#endif

#ifdef WR_FRAGMENT_SHADER
Fragment conic_gradient_brush_fs() {

#ifdef WR_FEATURE_ALPHA_PASS
// Handle top and left inflated edges (see brush_image).
vec2 local_pos = max(V_POS, vec2(0.0));

// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(local_pos, V_REPEATED_SIZE);

vec2 prim_size = V_REPEATED_SIZE * V_TILE_REPEAT;
// Handle bottom and right inflated edges (see brush_image).
if (local_pos.x >= prim_size.x) {
pos.x = V_REPEATED_SIZE.x;
}
if (local_pos.y >= prim_size.y) {
pos.y = V_REPEATED_SIZE.y;
}
#else
// Apply potential horizontal and vertical repetitions.
vec2 pos = mod(V_POS, V_REPEATED_SIZE);
#endif

vec2 current_dir = pos - V_CENTER;
float current_angle = atan(current_dir.y, current_dir.x) + (PI / 2 - V_ANGLE);
float offset = mod(current_angle / (2 * PI), 1.0);

vec4 color = sample_gradient(V_GRADIENT_ADDRESS,
offset,
V_GRADIENT_REPEAT);

#ifdef WR_FEATURE_ALPHA_PASS
color *= init_transform_fs(V_LOCAL_POS);
#endif

return Fragment(color);
}
#endif

// Undef macro names that could be re-defined by other shaders.
#undef V_GRADIENT_ADDRESS
#undef V_START_POINT
#undef V_SCALE_DIR
#undef V_REPEATED_SIZE
#undef V_GRADIENT_REPEAT
#undef V_POS
#undef V_LOCAL_POS
#undef V_TILE_REPEAT
@@ -18,10 +18,11 @@
#define BRUSH_KIND_TEXT 3
#define BRUSH_KIND_LINEAR_GRADIENT 4
#define BRUSH_KIND_RADIAL_GRADIENT 5
#define BRUSH_KIND_BLEND 6
#define BRUSH_KIND_MIX_BLEND 7
#define BRUSH_KIND_YV 8
#define BRUSH_KIND_OPACITY 9
#define BRUSH_KIND_CONIC_GRADIENT 6
#define BRUSH_KIND_BLEND 7
#define BRUSH_KIND_MIX_BLEND 8
#define BRUSH_KIND_YV 9
#define BRUSH_KIND_OPACITY 10

int vecs_per_brush(int brush_kind);

@@ -75,6 +76,14 @@ int vecs_per_brush(int brush_kind);
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION

#ifdef WR_FEATURE_CONIC_GRADIENT_BRUSH
#include brush_conic_gradient
#endif

#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION

#ifdef WR_FEATURE_OPACITY_BRUSH
#include brush_opacity
#endif
@@ -109,6 +118,11 @@ int vecs_per_brush(int brush_kind) {
case BRUSH_KIND_RADIAL_GRADIENT: return VECS_PER_RADIAL_GRADIENT_BRUSH;
#endif


#ifdef WR_FEATURE_CONIC_GRADIENT_BRUSH
case BRUSH_KIND_CONIC_GRADIENT: return VECS_PER_CONIC_GRADIENT_BRUSH;
#endif

#ifdef WR_FEATURE_OPACITY_BRUSH
case BRUSH_KIND_OPACITY: return VECS_PER_OPACITY_BRUSH;
#endif
@@ -173,6 +187,12 @@ void multi_brush_vs(
break;
#endif

#ifdef WR_FEATURE_CONIC_GRADIENT_BRUSH
case BRUSH_KIND_CONIC_GRADIENT:
conic_gradient_brush_vs(BRUSH_VS_PARAMS);
break;
#endif

#ifdef WR_FEATURE_OPACITY_BRUSH
case BRUSH_KIND_OPACITY:
opacity_brush_vs(BRUSH_VS_PARAMS);
@@ -213,6 +233,10 @@ Fragment multi_brush_fs(int brush_kind) {
case BRUSH_KIND_RADIAL_GRADIENT: return radial_gradient_brush_fs();
#endif

#ifdef WR_FEATURE_CONIC_GRADIENT_BRUSH
case BRUSH_KIND_CONIC_GRADIENT: return conic_gradient_brush_fs();
#endif

#ifdef WR_FEATURE_OPACITY_BRUSH
case BRUSH_KIND_OPACITY: return opacity_brush_fs();
#endif
@@ -56,6 +56,7 @@ pub enum BrushBatchKind {
backdrop_id: RenderTaskId,
},
YuvImage(ImageBufferKind, YuvFormat, ColorDepth, YuvColorSpace, ColorRange),
ConicGradient,
RadialGradient,
LinearGradient,
Opacity,
@@ -77,6 +78,7 @@ impl BatchKind {
BatchKind::Brush(BrushBatchKind::Image(..)) => BrushShaderKind::Image,
BatchKind::Brush(BrushBatchKind::LinearGradient) => BrushShaderKind::LinearGradient,
BatchKind::Brush(BrushBatchKind::RadialGradient) => BrushShaderKind::RadialGradient,
BatchKind::Brush(BrushBatchKind::ConicGradient) => BrushShaderKind::ConicGradient,
BatchKind::Brush(BrushBatchKind::Blend) => BrushShaderKind::Blend,
BatchKind::Brush(BrushBatchKind::MixBlend { .. }) => BrushShaderKind::MixBlend,
BatchKind::Brush(BrushBatchKind::YuvImage(..)) => BrushShaderKind::Yuv,
@@ -2330,6 +2332,87 @@ impl BatchBuilder {
);
}
}
PrimitiveInstanceKind::ConicGradient { data_handle, ref visible_tiles_range, .. } => {
let prim_data = &ctx.data_stores.conic_grad[data_handle];
let specified_blend_mode = BlendMode::PremultipliedAlpha;

let mut prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
specific_prim_address: GpuCacheAddress::INVALID,
transform_id,
};

if visible_tiles_range.is_empty() {
let non_segmented_blend_mode = if !prim_data.opacity.is_opaque ||
prim_info.clip_task_index != ClipTaskIndex::INVALID ||
transform_kind == TransformedRectKind::Complex
{
specified_blend_mode
} else {
BlendMode::None
};

let batch_params = BrushBatchParameters::shared(
BrushBatchKind::ConicGradient,
BatchTextures::no_texture(),
[
prim_data.stops_handle.as_int(gpu_cache),
0,
0,
0,
],
0,
);

prim_header.specific_prim_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);

let prim_header_index = prim_headers.push(
&prim_header,
z_id,
batch_params.prim_user_data,
);

let segments = if prim_data.brush_segments.is_empty() {
None
} else {
Some(prim_data.brush_segments.as_slice())
};

self.add_segmented_prim_to_batch(
segments,
prim_data.opacity,
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
render_tasks,
z_id,
prim_info.clip_task_index,
prim_vis_mask,
ctx,
);
} else {
let visible_tiles = &ctx.scratch.gradient_tiles[*visible_tiles_range];

self.add_gradient_tiles(
visible_tiles,
&prim_data.stops_handle,
BrushBatchKind::ConicGradient,
specified_blend_mode,
bounding_rect,
clip_task_address.unwrap(),
gpu_cache,
&prim_header,
prim_headers,
z_id,
prim_vis_mask,
);
}
}
PrimitiveInstanceKind::Backdrop { data_handle } => {
let prim_data = &ctx.data_stores.backdrop[data_handle];
let backdrop_pic_index = prim_data.kind.pic_index;
@@ -78,10 +78,11 @@ pub enum BrushShaderKind {
Text = 3,
LinearGradient = 4,
RadialGradient = 5,
Blend = 6,
MixBlend = 7,
Yuv = 8,
Opacity = 9,
ConicGradient = 6,
Blend = 7,
MixBlend = 8,
Yuv = 9,
Opacity = 10,
}

#[derive(Debug, Copy, Clone)]
@@ -122,7 +122,7 @@ use crate::prim_store::backdrop::Backdrop;
#[cfg(any(feature = "capture", feature = "replay"))]
use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
#[cfg(any(feature = "capture", feature = "replay"))]
use crate::prim_store::gradient::{LinearGradient, RadialGradient};
use crate::prim_store::gradient::{LinearGradient, RadialGradient, ConicGradient};
#[cfg(any(feature = "capture", feature = "replay"))]
use crate::prim_store::image::{Image, YuvImage};
#[cfg(any(feature = "capture", feature = "replay"))]
@@ -2714,6 +2714,7 @@ impl TileCacheInstance {
PrimitiveInstanceKind::NormalBorder { .. } |
PrimitiveInstanceKind::LinearGradient { .. } |
PrimitiveInstanceKind::RadialGradient { .. } |
PrimitiveInstanceKind::ConicGradient { .. } |
PrimitiveInstanceKind::Backdrop { .. } => {
// These don't contribute dependencies
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.