From 9544191ab5e0b24eb845347572c7a7bcce95d303 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 5 Mar 2019 12:46:45 -0800 Subject: [PATCH 1/3] improve elevation bounds --- flow/layers/physical_shape_layer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 841ae4cf6a076..b5ac60f8911df 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -51,11 +51,11 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, set_needs_system_composite(true); #else // Add some margin to the paint bounds to leave space for the shadow. - // The margin is hardcoded to an arbitrary maximum for now because Skia + // The margin is set to a multiple of elevation_ for now because Skia // doesn't provide a way to calculate it. We fill this whole region // and clip children to it so we don't need to join the child paint bounds. SkRect bounds(path_.getBounds()); - bounds.outset(20.0, 20.0); + bounds.outset(elevation_ * 1.5, elevation_ * 1.5); set_paint_bounds(bounds); #endif // defined(OS_FUCHSIA) } From 50dae57e456c61d9596fb92f5161a7a97682948d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 5 Mar 2019 15:08:03 -0800 Subject: [PATCH 2/3] update calculation --- flow/layers/physical_shape_layer.cc | 31 +++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index b5ac60f8911df..77727cb2d86a3 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -9,6 +9,9 @@ namespace flow { +const SkScalar kLightHeight = 600; +const SkScalar kLightRadius = 800; + PhysicalShapeLayer::PhysicalShapeLayer(Clip clip_behavior) : isRect_(false), clip_behavior_(clip_behavior) {} @@ -51,11 +54,29 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, set_needs_system_composite(true); #else // Add some margin to the paint bounds to leave space for the shadow. - // The margin is set to a multiple of elevation_ for now because Skia - // doesn't provide a way to calculate it. We fill this whole region - // and clip children to it so we don't need to join the child paint bounds. + // We fill this whole region and clip children to it so we don't need to + // join the child paint bounds. + // The offset is calculated as follows: + + // .-- (kLightRadius = 800) + // ----- (light) + // | (kLightHeight = 600) + // ------------- (layer) + // | + // | (elevation) + // | + // ------------------------------------------------ (canvas) + // ----------- (extent of shadow) + // + // E = lx } x = (r + w/2)/h + // } => + // r + w/2 = hx } E = (l/h)(r + w/2) SkRect bounds(path_.getBounds()); - bounds.outset(elevation_ * 1.5, elevation_ * 1.5); + double ex = (kLightRadius * device_pixel_ratio_ + bounds.width() * 0.5) / + kLightHeight; + double ey = (kLightRadius * device_pixel_ratio_ + bounds.height() * 0.5) / + kLightHeight; + bounds.outset(elevation_ * ex, elevation_ * ey); set_paint_bounds(bounds); #endif // defined(OS_FUCHSIA) } @@ -145,8 +166,6 @@ void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, SkScalar dpr) { const SkScalar kAmbientAlpha = 0.039f; const SkScalar kSpotAlpha = 0.25f; - const SkScalar kLightHeight = 600; - const SkScalar kLightRadius = 800; SkShadowFlags flags = transparentOccluder ? SkShadowFlags::kTransparentOccluder_ShadowFlag From 5159ec28e03663a1166f3ee5726684b01c4837f6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 5 Mar 2019 15:59:40 -0800 Subject: [PATCH 3/3] update diagram --- flow/layers/physical_shape_layer.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index 77727cb2d86a3..d022ccb223305 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -71,6 +71,13 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, // E = lx } x = (r + w/2)/h // } => // r + w/2 = hx } E = (l/h)(r + w/2) + // + // Where: E = extent of shadow + // l = elevation of layer + // r = radius of the light source + // w = width of the layer + // h = light height + // x = multiplier for elevation to extent SkRect bounds(path_.getBounds()); double ex = (kLightRadius * device_pixel_ratio_ + bounds.width() * 0.5) / kLightHeight;