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

Box shadow with border radius properly clips #950

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Box shadow with border radius properly clips

  • Loading branch information
changm committed Mar 2, 2017
commit c1bf1542fc6cb9d94bcc59a7682678bab9b3d538
@@ -22,6 +22,7 @@ use webrender_traits::{BlobImageData, BlobImageDescriptor, BlobImageError, BlobI
use webrender_traits::{BlobImageResult, ClipRegion, ColorF, DeviceUintSize, Epoch, GlyphInstance};
use webrender_traits::{ImageData, ImageDescriptor, ImageFormat, ImageKey, ImageRendering};
use webrender_traits::{LayoutPoint, LayoutRect, LayoutSize, PipelineId, RasterizedBlobImage};
use webrender_traits::{BoxShadowClipMode};


fn load_file(name: &str) -> Vec<u8> {
@@ -100,7 +101,7 @@ fn main() {
renderer.set_render_notifier(notifier);

let epoch = Epoch(0);
let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);
let root_background_color = ColorF::new(1.0, 1.0, 1.0, 1.0);

let vector_img = api.generate_image_key();
api.add_image(
@@ -121,6 +122,7 @@ fn main() {

builder.new_clip_region(&bounds, vec![complex], None)
};
let full_screen_clip = builder.new_clip_region(&bounds, vec![], None);

builder.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
bounds,
@@ -130,6 +132,7 @@ fn main() {
None,
webrender_traits::MixBlendMode::Normal,
Vec::new());

builder.push_image(
LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(100.0, 100.0)),
ClipRegion::simple(&bounds),
@@ -187,7 +190,6 @@ fn main() {
border_widths,
border_details);


if false { // draw text?
let font_key = api.generate_font_key();
let font_bytes = load_file("res/FreeSans.ttf");
@@ -256,6 +258,48 @@ fn main() {
None);
}

if true { // draw box shadow?
let rect = LayoutRect::new(LayoutPoint::new(0.0, 0.0), LayoutSize::new(0.0, 0.0));
let simple_box_bounds = LayoutRect::new(LayoutPoint::new(300.0, 300.0), LayoutSize::new(100.0, 100.0));
let offset = LayoutPoint::new(0.0, 0.0);
let color = ColorF::new(0.0, 0.0, 0.0, 1.0);
let blur_radius = 10.0;
let spread_radius = 0.0;
let simple_border_radius = 10.0;
let box_shadow_type = BoxShadowClipMode::Inset;

builder.push_box_shadow(rect,
full_screen_clip,
simple_box_bounds,
offset,
color,
blur_radius,
spread_radius,
simple_border_radius,
BoxShadowClipMode::Outset);

let curved_box_bounds = LayoutRect::new(LayoutPoint::new(500.0, 500.0), LayoutSize::new(100.0, 100.0));
let border_radius = 20.0;
let blur_clip = {
let complex = webrender_traits::ComplexClipRegion::new(
curved_box_bounds,
webrender_traits::BorderRadius::uniform(border_radius)
);

builder.new_clip_region(&bounds, vec![complex], None)
};

builder.push_box_shadow(rect,
blur_clip,
curved_box_bounds,
offset,
color,
blur_radius,
spread_radius,
border_radius,
box_shadow_type);
}

builder.pop_stacking_context();

api.set_root_display_list(
@@ -6,4 +6,14 @@ void main(void) {
vec2 uv = min(vec2(1.0), vMirrorPoint - abs(vUv.xy - vMirrorPoint));
uv = mix(vCacheUvRectCoords.xy, vCacheUvRectCoords.zw, uv);
oFragColor = vColor * texture(sCache, vec3(uv, vUv.z));

#ifdef WR_FEATURE_CLIP
float alpha = 1.0;
alpha = min(alpha, do_clip());

// Need to do an inverted clip here iff we have a complex clip
// and we're an outer box shadow.
alpha = vIsInset == 1.0 ? alpha : 1.0 - alpha;
oFragColor = oFragColor * vec4(1.0, 1.0, 1.0, alpha);
#endif
}
@@ -7,3 +7,4 @@ flat varying vec4 vColor;
varying vec3 vUv;
flat varying vec2 vMirrorPoint;
flat varying vec4 vCacheUvRectCoords;
flat varying float vIsInset;
@@ -29,4 +29,9 @@ void main(void) {
vCacheUvRectCoords = vec4(patch_origin, patch_origin + patch_size_device_pixels) / texture_size.xyxy;

vColor = bs.color;
vIsInset = bs.border_radius_edge_size_blur_radius_inverted.w;

#ifdef WR_FEATURE_CLIP
write_clip(vi.screen_pos, prim.clip_area);
#endif
}
@@ -770,7 +770,8 @@ impl FrameBuilder {
// to draw. In the simple case (no blur radius), we can
// just draw these as solid colors.
let mut rects = Vec::new();
subtract_rect(&outer_rect, box_bounds, &mut rects);
let inner_rect = bs_rect.inflate(-border_radius, -border_radius);
subtract_rect(&outer_rect, &inner_rect, &mut rects);
if edge_size == 0.0 {
BoxShadowKind::Simple(rects)
} else {
@@ -809,7 +809,7 @@ impl PrimitiveStore {
let metadata = PrimitiveMetadata {
is_opaque: false,
clip_source: clip_source,
clip_cache_info: None,
clip_cache_info: clip_info,
prim_kind: PrimitiveKind::BoxShadow,
cpu_prim_index: SpecificPrimitiveIndex::invalid(),
gpu_prim_index: gpu_prim_address,
@@ -416,6 +416,7 @@ pub struct Renderer {
ps_angle_gradient: PrimitiveShader,
ps_radial_gradient: PrimitiveShader,
ps_box_shadow: PrimitiveShader,
ps_box_shadow_clip: PrimitiveShader,
ps_cache_image: PrimitiveShader,

ps_blend: LazilyCompiledShader,
@@ -624,6 +625,13 @@ impl Renderer {
options.precache_shaders)
};

let ps_box_shadow_clip = try!{
PrimitiveShader::new("ps_box_shadow",
&mut device,
&[ CLIP_FEATURE ],
options.precache_shaders)
};

let ps_gradient = try!{
PrimitiveShader::new("ps_gradient",
&mut device,
@@ -824,6 +832,7 @@ impl Renderer {
ps_yuv_image: ps_yuv_image,
ps_border: ps_border,
ps_box_shadow: ps_box_shadow,
ps_box_shadow_clip: ps_box_shadow_clip,
ps_gradient: ps_gradient,
ps_angle_gradient: ps_angle_gradient,
ps_radial_gradient: ps_radial_gradient,
@@ -1230,7 +1239,11 @@ impl Renderer {
(GPU_TAG_PRIM_RADIAL_GRADIENT, shader)
}
AlphaBatchKind::BoxShadow => {
let shader = self.ps_box_shadow.get(&mut self.device, transform_kind);
let shader = if needs_clipping {
self.ps_box_shadow_clip.get(&mut self.device, transform_kind)
} else {
self.ps_box_shadow.get(&mut self.device, transform_kind)
};
(GPU_TAG_PRIM_BOX_SHADOW, shader)
}
AlphaBatchKind::CacheImage => {
@@ -0,0 +1,10 @@
---
root:
items:
- type: stacking_context
bounds: [0, 0, 200, 200]
items:
- type: rect
bounds: [ 10, 10, 80, 80 ]
color: [255, 255, 255]

@@ -0,0 +1,29 @@
---
root:
items:
- type: stacking_context
bounds: [0, 0, 200, 200]
items:
- type: box_shadow
bounds: [ 10, 10, 80, 80 ]
blur_radius: 5
spread_radius: 0
border_radius: 30
clip_mode: outset
clip:
{rect: [ 0, 0, 200, 200],
complex: [ { rect: [10, 10, 80, 80], radius: 30 } ]
}

- type: rect
bounds: [ 0, 0, 100, 10]
color: [255, 255, 255]
- type: rect
bounds: [ 0, 0, 10, 100]
color: [255, 255, 255]
- type: rect
bounds: [ 90, 0, 10, 100]
color: [255, 255, 255]
- type: rect
bounds: [ 0, 90, 100, 10]
color: [255, 255, 255]
@@ -1,2 +1,4 @@

!= inset-simple.yaml inset-simple-ref.yaml
!= inset-spread.yaml inset-spread-ref.yaml
!= box-border-radius.yaml box-border-radius-ref.yaml
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.