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

Shared clip source for the shaders #444

Merged
merged 3 commits into from Oct 14, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -0,0 +1,50 @@
/* 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/. */

flat varying vec4 vClipRect;
flat varying vec4 vClipRadius;

#ifdef WR_VERTEX_SHADER
void write_clip(Clip clip) {
vClipRect = vec4(clip.rect.xy, clip.rect.xy + clip.rect.zw);
vClipRadius = vec4(clip.top_left.outer_inner_radius.x,
clip.top_right.outer_inner_radius.x,
clip.bottom_right.outer_inner_radius.x,
clip.bottom_left.outer_inner_radius.x);
}
#endif

#ifdef WR_FRAGMENT_SHADER
float do_clip(vec2 pos) {
vec2 ref_tl = vClipRect.xy + vec2( vClipRadius.x, vClipRadius.x);
vec2 ref_tr = vClipRect.zy + vec2(-vClipRadius.y, vClipRadius.y);
vec2 ref_br = vClipRect.zw + vec2(-vClipRadius.z, -vClipRadius.z);
vec2 ref_bl = vClipRect.xw + vec2( vClipRadius.w, -vClipRadius.w);

float d_tl = distance(pos, ref_tl);
float d_tr = distance(pos, ref_tr);
float d_br = distance(pos, ref_br);
float d_bl = distance(pos, ref_bl);

float pixels_per_fragment = length(fwidth(pos.xy));
// TODO: compute the `nudge` separately for X and Y
float nudge = 0.5 * pixels_per_fragment;

bool out0 = pos.x < ref_tl.x && pos.y < ref_tl.y && d_tl > vClipRadius.x - nudge;
bool out1 = pos.x > ref_tr.x && pos.y < ref_tr.y && d_tr > vClipRadius.y - nudge;
bool out2 = pos.x > ref_br.x && pos.y > ref_br.y && d_br > vClipRadius.z - nudge;
bool out3 = pos.x < ref_bl.x && pos.y > ref_bl.y && d_bl > vClipRadius.w - nudge;

vec4 distances = vec4(d_tl, d_tr, d_br, d_bl) - vClipRadius + nudge;
float distance_from_border = dot(vec4(out0, out1, out2, out3), distances);

// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;

// Apply a more gradual fade out to transparent.
//distance_from_border -= 0.5;

return 1.0 - smoothstep(0.0, 1.0, distance_from_border);
}
#endif
@@ -545,39 +545,6 @@ Composite fetch_composite(int index) {
#endif

#ifdef WR_FRAGMENT_SHADER
float do_clip(vec2 pos, vec4 clip_rect, vec4 radius) {
vec2 ref_tl = clip_rect.xy + vec2( radius.x, radius.x);
vec2 ref_tr = clip_rect.zy + vec2(-radius.y, radius.y);
vec2 ref_br = clip_rect.zw + vec2(-radius.z, -radius.z);
vec2 ref_bl = clip_rect.xw + vec2( radius.w, -radius.w);

float d_tl = distance(pos, ref_tl);
float d_tr = distance(pos, ref_tr);
float d_br = distance(pos, ref_br);
float d_bl = distance(pos, ref_bl);

float pixels_per_fragment = length(fwidth(pos.xy));
float nudge = 0.5 * pixels_per_fragment;

bool out0 = pos.x < ref_tl.x && pos.y < ref_tl.y && d_tl > radius.x - nudge;
bool out1 = pos.x > ref_tr.x && pos.y < ref_tr.y && d_tr > radius.y - nudge;
bool out2 = pos.x > ref_br.x && pos.y > ref_br.y && d_br > radius.z - nudge;
bool out3 = pos.x < ref_bl.x && pos.y > ref_bl.y && d_bl > radius.w - nudge;

float distance_from_border = (float(out0) * (d_tl - radius.x + nudge)) +
(float(out1) * (d_tr - radius.y + nudge)) +
(float(out2) * (d_br - radius.z + nudge)) +
(float(out3) * (d_bl - radius.w + nudge));

// Move the distance back into pixels.
distance_from_border /= pixels_per_fragment;

// Apply a more gradual fade out to transparent.
//distance_from_border -= 0.5;

return smoothstep(1.0, 0.0, distance_from_border);
}

float squared_distance_from_rect(vec2 p, vec2 origin, vec2 size) {
vec2 clamped = clamp(p, origin, origin + size);
return distance(clamped, p);
@@ -11,7 +11,7 @@ void main(void) {
vec2 local_pos = vPos;
#endif

alpha = min(alpha, do_clip(local_pos, vClipRect, vClipRadius));
alpha = min(alpha, do_clip(local_pos));
oFragColor = mix(vColor0, vColor1, vF) * vec4(1, 1, 1, alpha);

#ifdef WR_FEATURE_TRANSFORM
@@ -4,8 +4,6 @@

flat varying vec4 vColor0;
flat varying vec4 vColor1;
flat varying vec4 vClipRect;
flat varying vec4 vClipRadius;
varying float vF;

#ifdef WR_FEATURE_TRANSFORM
@@ -29,11 +29,7 @@ void main(void) {
break;
}

vClipRect = vec4(gradient.clip.rect.xy, gradient.clip.rect.xy + gradient.clip.rect.zw);
vClipRadius = vec4(gradient.clip.top_left.outer_inner_radius.x,
gradient.clip.top_right.outer_inner_radius.x,
gradient.clip.bottom_right.outer_inner_radius.x,
gradient.clip.bottom_left.outer_inner_radius.x);
write_clip(gradient.clip);

vColor0 = gradient.color0;
vColor1 = gradient.color1;
@@ -19,7 +19,7 @@ void main(void) {
vec2 relative_pos_in_rect = vLocalPos - vLocalRect.xy;
#endif

alpha = min(alpha, do_clip(local_pos, vClipRect, vClipRadius));
alpha = min(alpha, do_clip(local_pos));

// We calculate the particular tile this fragment belongs to, taking into
// account the spacing in between tiles. We only paint if our fragment does
@@ -6,8 +6,6 @@ flat varying vec2 vTextureOffset; // Offset of this image into the texture atlas
flat varying vec2 vTextureSize; // Size of the image in the texture atlas.
flat varying vec2 vTileSpacing; // Amount of space between tiled instances of this image.
flat varying vec2 vStretchSize;
flat varying vec4 vClipRect;
flat varying vec4 vClipRadius;
flat varying vec4 vLocalRect;

#ifdef WR_FEATURE_TRANSFORM
@@ -15,11 +15,7 @@ void main(void) {
vLocalRect = image.info.local_rect;
#endif

vClipRect = vec4(image.clip.rect.xy, image.clip.rect.xy + image.clip.rect.zw);
vClipRadius = vec4(image.clip.top_left.outer_inner_radius.x,
image.clip.top_right.outer_inner_radius.x,
image.clip.bottom_right.outer_inner_radius.x,
image.clip.bottom_left.outer_inner_radius.x);
write_clip(image.clip);

vec2 st0 = image.st_rect.xy;
vec2 st1 = image.st_rect.zw;
@@ -11,6 +11,6 @@ void main(void) {
vec2 local_pos = vPos;
#endif

alpha = min(alpha, do_clip(local_pos, vClipRect, vClipRadius));
alpha = min(alpha, do_clip(local_pos));
oFragColor = vColor * vec4(1, 1, 1, alpha);
}
@@ -5,8 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

varying vec4 vColor;
flat varying vec4 vClipRect;
flat varying vec4 vClipRadius;

#ifdef WR_FEATURE_TRANSFORM
varying vec3 vPos;
@@ -15,11 +15,7 @@ void main(void) {
vPos = vi.local_clamped_pos;
#endif

vClipRect = vec4(rect.clip.rect.xy, rect.clip.rect.xy + rect.clip.rect.zw);
vClipRadius = vec4(rect.clip.top_left.outer_inner_radius.x,
rect.clip.top_right.outer_inner_radius.x,
rect.clip.bottom_right.outer_inner_radius.x,
rect.clip.bottom_left.outer_inner_radius.x);
write_clip(rect.clip);

vColor = rect.color;
}
@@ -1155,37 +1155,33 @@ impl Device {
pub fn create_program(&mut self,
base_filename: &str,
include_filename: &str) -> ProgramId {
self.create_program_with_prefix(base_filename, include_filename, None)
self.create_program_with_prefix(base_filename, &[include_filename], None)
}

pub fn create_program_with_prefix(&mut self,
base_filename: &str,
include_filename: &str,
include_filenames: &[&str],
prefix: Option<String>) -> ProgramId {
debug_assert!(self.inside_frame);

let pid = gl::create_program();
let base_path = self.resource_path.join(base_filename);

let mut vs_path = self.resource_path.clone();
vs_path.push(&format!("{}.vs.glsl", base_filename));
let vs_path = base_path.with_extension("vs.glsl");
//self.file_watcher.add_watch(vs_path.clone());

let mut fs_path = self.resource_path.clone();
fs_path.push(&format!("{}.fs.glsl", base_filename));
let fs_path = base_path.with_extension("fs.glsl");
//self.file_watcher.add_watch(fs_path.clone());

let mut include_path = self.resource_path.clone();
include_path.push(&format!("{}.glsl", include_filename));
let mut f = File::open(&include_path).unwrap();
let mut include = String::new();
f.read_to_string(&mut include).unwrap();
for inc_filename in include_filenames {
let include_path = self.resource_path.join(inc_filename).with_extension("glsl");
File::open(&include_path).unwrap().read_to_string(&mut include).unwrap();
}

let mut shared_path = self.resource_path.clone();
shared_path.push(&format!("{}.glsl", base_filename));
let shared_path = base_path.with_extension("glsl");
if let Ok(mut f) = File::open(&shared_path) {
let mut shared_code = String::new();
f.read_to_string(&mut shared_code).unwrap();
include.push_str(&shared_code);
f.read_to_string(&mut include).unwrap();
}

let program = Program {
@@ -269,8 +269,15 @@ fn create_prim_shader(name: &'static str,
prefix.push_str(&format!("#define WR_FEATURE_{}\n", feature));
}

let includes_base = ["prim_shared"];
let includes_clip = ["prim_shared", "clip_shared"];
let includes: &[&str] = if name.ends_with("_clip") {
&includes_clip
} else {
&includes_base
};
let program_id = device.create_program_with_prefix(name,
"prim_shared",
includes,
Some(prefix));

let data_index = gl::get_uniform_block_index(program_id.0, "Data");
@@ -288,8 +295,9 @@ fn create_clear_shader(name: &'static str,
max_ubo_vectors: usize) -> ProgramId {
let prefix = format!("#define WR_MAX_UBO_VECTORS {}", max_ubo_vectors);

let includes = &["shared_other"];
let program_id = device.create_program_with_prefix(name,
"shared_other",
includes,
Some(prefix));

let data_index = gl::get_uniform_block_index(program_id.0, "Data");
@@ -453,7 +461,7 @@ impl Renderer {
max_prim_box_shadows,
&mut device,
options.precache_shaders);
let ps_aligned_gradient = PrimitiveShader::new("ps_gradient",
let ps_aligned_gradient = PrimitiveShader::new("ps_gradient_clip",
max_ubo_vectors,
max_prim_aligned_gradients,
&mut device,
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.