diff options
Diffstat (limited to 'libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp')
-rw-r--r-- | libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp | 524 |
1 files changed, 8 insertions, 516 deletions
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp index d05e7f660c72..2ead5c5897d2 100644 --- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp +++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp @@ -24,6 +24,7 @@ #include <SkGaussianEdgeShader.h> #include <SkPathOps.h> #include <SkRRectsGaussianEdgeMaskFilter.h> +#include <SkShadowUtils.h> namespace android { namespace uirenderer { @@ -115,498 +116,6 @@ void EndReorderBarrierDrawable::onDraw(SkCanvas* canvas) { } } -/** - * @param canvas the destination for the shadow draws - * @param shape the shape casting the shadow - * @param casterZValue the Z value of the caster RRect - * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow - * @param draw the function used to draw 'shape' - */ -template <typename Shape, typename F> -static void DrawAmbientShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue, - float ambientAlpha, F&& draw) { - if (ambientAlpha <= 0) { - return; - } - - const float kHeightFactor = 1.f/128.f; - const float kGeomFactor = 64; - - float umbraAlpha = 1 / (1 + SkMaxScalar(casterZValue*kHeightFactor, 0)); - float radius = casterZValue*kHeightFactor*kGeomFactor; - - sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle, - SkBlurMask::ConvertRadiusToSigma(radius), SkBlurMaskFilter::kNone_BlurFlag); - SkPaint paint; - paint.setAntiAlias(true); - paint.setMaskFilter(std::move(mf)); - paint.setARGB(ambientAlpha*umbraAlpha, 0, 0, 0); - - draw(shape, paint); -} - -/** - * @param canvas the destination for the shadow draws - * @param shape the shape casting the shadow - * @param casterZValue the Z value of the caster RRect - * @param lightPos the position of the light casting the shadow - * @param lightWidth - * @param spotAlpha the maximum alpha value to use when drawing the spot shadow - * @param draw the function used to draw 'shape' - */ -template <typename Shape, typename F> -static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue, - float spotAlpha, F&& draw) { - if (spotAlpha <= 0) { - return; - } - - const Vector3 lightPos = SkiaPipeline::getLightCenter(); - float zRatio = casterZValue / (lightPos.z - casterZValue); - // clamp - if (zRatio < 0.0f) { - zRatio = 0.0f; - } else if (zRatio > 0.95f) { - zRatio = 0.95f; - } - - float blurRadius = SkiaPipeline::getLightRadius()*zRatio; - - SkAutoCanvasRestore acr(canvas, true); - - sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle, - SkBlurMask::ConvertRadiusToSigma(blurRadius), SkBlurMaskFilter::kNone_BlurFlag); - - SkPaint paint; - paint.setAntiAlias(true); - paint.setMaskFilter(std::move(mf)); - paint.setARGB(spotAlpha, 0, 0, 0); - - // approximate projection by translating and scaling projected offset of bounds center - // TODO: compute the actual 2D projection - SkScalar scale = lightPos.z / (lightPos.z - casterZValue); - canvas->scale(scale, scale); - SkPoint center = SkPoint::Make(shape.getBounds().centerX(), shape.getBounds().centerY()); - SkMatrix ctmInverse; - if (!canvas->getTotalMatrix().invert(&ctmInverse)) { - ALOGW("Matrix is degenerate. Will not render shadow!"); - return; - } - SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y); - ctmInverse.mapPoints(&lightPos2D, 1); - canvas->translate(zRatio*(center.fX - lightPos2D.fX), zRatio*(center.fY - lightPos2D.fY)); - - draw(shape, paint); -} - -#define MAX_BLUR_RADIUS 16383.75f -#define MAX_PAD 64 - -/** - * @param casterRect the rectangle bounds of the RRect casting the shadow - * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow - * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow - * @param spotAlpha the maximum alpha value to use when drawing the spot shadow - * @param casterAlpha the alpha value of the RRect casting the shadow (0.0-1.0 range) - * @param casterZValue the Z value of the caster RRect - * @param scaleFactor the scale needed to map from src-space to device-space - * @param canvas the destination for the shadow draws - */ -static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius, - SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, - SkScalar scaleFactor, SkCanvas* canvas) { - SkASSERT(casterCornerRadius >= 0.0f); - - // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space - const SkScalar minRadius = 0.5f / scaleFactor; - - const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()), - SkScalarHalf(casterRect.height())); - const bool isRect = casterCornerRadius <= minRadius; - - sk_sp<SkShader> edgeShader(SkGaussianEdgeShader::Make()); - - if (ambientAlpha > 0.0f) { - static const float kHeightFactor = 1.0f / 128.0f; - static const float kGeomFactor = 64.0f; - - SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor; - // the device-space radius sent to the blur shader must fit in 14.2 fixed point - if (srcSpaceAmbientRadius*scaleFactor > MAX_BLUR_RADIUS) { - srcSpaceAmbientRadius = MAX_BLUR_RADIUS/scaleFactor; - } - const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f)); - const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha; - - // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius - // to get our stroke shape. - SkScalar ambientPathOutset = std::max(ambientOffset - srcSpaceAmbientRadius * 0.5f, - minRadius); - - SkRRect ambientRRect; - const SkRect temp = casterRect.makeOutset(ambientPathOutset, ambientPathOutset); - if (isOval) { - ambientRRect = SkRRect::MakeOval(temp); - } else if (isRect) { - ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset); - } else { - ambientRRect = SkRRect::MakeRectXY(temp, casterCornerRadius + ambientPathOutset, - casterCornerRadius + ambientPathOutset); - } - - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - // we outset the stroke a little to cover up AA on the interior edge - float pad = 0.5f; - paint.setStrokeWidth(srcSpaceAmbientRadius + 2.0f * pad); - // handle scale of radius and pad due to CTM - pad *= scaleFactor; - const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor; - SkASSERT(devSpaceAmbientRadius <= MAX_BLUR_RADIUS); - SkASSERT(pad < MAX_PAD); - // convert devSpaceAmbientRadius to 14.2 fixed point and place in the R & G components - // convert pad to 6.2 fixed point and place in the B component - uint16_t iDevSpaceAmbientRadius = (uint16_t)(4.0f * devSpaceAmbientRadius); - paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, iDevSpaceAmbientRadius >> 8, - iDevSpaceAmbientRadius & 0xff, (unsigned char)(4.0f * pad))); - - paint.setShader(edgeShader); - canvas->drawRRect(ambientRRect, paint); - } - - if (spotAlpha > 0.0f) { - const Vector3 lightPos = SkiaPipeline::getLightCenter(); - float zRatio = casterZValue / (lightPos.z - casterZValue); - // clamp - if (zRatio < 0.0f) { - zRatio = 0.0f; - } else if (zRatio > 0.95f) { - zRatio = 0.95f; - } - - const SkScalar lightWidth = SkiaPipeline::getLightRadius(); - SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio; - // the device-space radius sent to the blur shader must fit in 14.2 fixed point - if (srcSpaceSpotRadius*scaleFactor > MAX_BLUR_RADIUS) { - srcSpaceSpotRadius = MAX_BLUR_RADIUS/scaleFactor; - } - - SkRRect spotRRect; - if (isOval) { - spotRRect = SkRRect::MakeOval(casterRect); - } else if (isRect) { - spotRRect = SkRRect::MakeRectXY(casterRect, minRadius, minRadius); - } else { - spotRRect = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius); - } - - SkRRect spotShadowRRect; - // Compute the scale and translation for the spot shadow. - const SkScalar scale = lightPos.z / (lightPos.z - casterZValue); - spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect); - - SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(), - spotShadowRRect.rect().centerY()); - SkMatrix ctmInverse; - if (!canvas->getTotalMatrix().invert(&ctmInverse)) { - ALOGW("Matrix is degenerate. Will not render spot shadow!"); - return; - } - SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y); - ctmInverse.mapPoints(&lightPos2D, 1); - const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX), - zRatio*(center.fY - lightPos2D.fY)); - - SkAutoCanvasRestore acr(canvas, true); - - // We want to extend the stroked area in so that it meets up with the caster - // geometry. The stroked geometry will, by definition already be inset half the - // stroke width but we also have to account for the scaling. - // We also add 1/2 to cover up AA on the interior edge. - SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(casterRect.fLeft), - SkTAbs(casterRect.fRight)), SkTMax(SkTAbs(casterRect.fTop), - SkTAbs(casterRect.fBottom))); - SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) + - scaleOffset + 0.5f; - - // Compute area - SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount; - SkScalar strokedArea = 2.0f*strokeWidth * (spotShadowRRect.width() - + spotShadowRRect.height()); - SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius) - * (spotShadowRRect.width() + srcSpaceSpotRadius); - - SkPaint paint; - paint.setAntiAlias(true); - - // If the area of the stroked geometry is larger than the fill geometry, just fill it. - if (strokedArea > filledArea || casterAlpha < 1.0f || insetAmount < 0.0f) { - paint.setStyle(SkPaint::kStrokeAndFill_Style); - paint.setStrokeWidth(srcSpaceSpotRadius); - } else { - // Since we can't have unequal strokes, inset the shadow rect so the inner - // and outer edges of the stroke will land where we want. - SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount/2.0f, insetAmount/2.0f); - SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount/2.0f, - minRadius); - spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad); - paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(strokeWidth); - } - - // handle scale of radius and pad due to CTM - const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor; - SkASSERT(devSpaceSpotRadius <= MAX_BLUR_RADIUS); - - const SkScalar devSpaceSpotPad = 0; - SkASSERT(devSpaceSpotPad < MAX_PAD); - - // convert devSpaceSpotRadius to 14.2 fixed point and place in the R & G - // components convert devSpaceSpotPad to 6.2 fixed point and place in the B component - uint16_t iDevSpaceSpotRadius = (uint16_t)(4.0f * devSpaceSpotRadius); - paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, iDevSpaceSpotRadius >> 8, - iDevSpaceSpotRadius & 0xff, (unsigned char)(4.0f * devSpaceSpotPad))); - paint.setShader(edgeShader); - - canvas->translate(spotOffset.fX, spotOffset.fY); - canvas->drawRRect(spotShadowRRect, paint); - } -} - -/** - * @param casterRect the rectangle bounds of the RRect casting the shadow - * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow - * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow - * @param spotAlpha the maximum alpha value to use when drawing the spot shadow - * @param casterZValue the Z value of the caster RRect - * @param scaleFactor the scale needed to map from src-space to device-space - * @param clipRR the oval or rect with which the drawn roundrect must be intersected - * @param canvas the destination for the shadow draws - */ -static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius, - SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor, - const SkRRect& clipRR, SkCanvas* canvas) { - SkASSERT(casterCornerRadius >= 0.0f); - - const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()), - SkScalarHalf(casterRect.height())); - - if (ambientAlpha > 0.0f) { - static const float kHeightFactor = 1.0f / 128.0f; - static const float kGeomFactor = 64.0f; - - const SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor; - const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor; - - const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f)); - const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha; - - const SkRect srcSpaceAmbientRect = casterRect.makeOutset(ambientOffset, ambientOffset); - SkRect devSpaceAmbientRect; - canvas->getTotalMatrix().mapRect(&devSpaceAmbientRect, srcSpaceAmbientRect); - - SkRRect devSpaceAmbientRRect; - if (isOval) { - devSpaceAmbientRRect = SkRRect::MakeOval(devSpaceAmbientRect); - } else { - const SkScalar devSpaceCornerRadius = scaleFactor * (casterCornerRadius + ambientOffset); - devSpaceAmbientRRect = SkRRect::MakeRectXY(devSpaceAmbientRect, devSpaceCornerRadius, - devSpaceCornerRadius); - } - - const SkRect srcSpaceAmbClipRect = clipRR.rect().makeOutset(ambientOffset, ambientOffset); - SkRect devSpaceAmbClipRect; - canvas->getTotalMatrix().mapRect(&devSpaceAmbClipRect, srcSpaceAmbClipRect); - SkRRect devSpaceAmbientClipRR; - if (clipRR.isOval()) { - devSpaceAmbientClipRR = SkRRect::MakeOval(devSpaceAmbClipRect); - } else { - SkASSERT(clipRR.isRect()); - devSpaceAmbientClipRR = SkRRect::MakeRect(devSpaceAmbClipRect); - } - - SkRect cover = srcSpaceAmbClipRect; - if (!cover.intersect(srcSpaceAmbientRect)) { - return; - } - - SkPaint paint; - paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, 0, 0, 0)); - paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceAmbientRRect, - devSpaceAmbientClipRR, devSpaceAmbientRadius)); - canvas->drawRect(cover, paint); - } - - if (spotAlpha > 0.0f) { - const Vector3 lightPos = SkiaPipeline::getLightCenter(); - float zRatio = casterZValue / (lightPos.z - casterZValue); - // clamp - if (zRatio < 0.0f) { - zRatio = 0.0f; - } else if (zRatio > 0.95f) { - zRatio = 0.95f; - } - - const SkScalar lightWidth = SkiaPipeline::getLightRadius(); - const SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio; - const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor; - - // Compute the scale and translation for the spot shadow. - const SkScalar scale = lightPos.z / (lightPos.z - casterZValue); - const SkMatrix spotMatrix = SkMatrix::MakeScale(scale, scale); - - SkRect srcSpaceScaledRect = casterRect; - spotMatrix.mapRect(&srcSpaceScaledRect); - srcSpaceScaledRect.outset(SkScalarHalf(srcSpaceSpotRadius), - SkScalarHalf(srcSpaceSpotRadius)); - - SkRRect srcSpaceSpotRRect; - if (isOval) { - srcSpaceSpotRRect = SkRRect::MakeOval(srcSpaceScaledRect); - } else { - srcSpaceSpotRRect = SkRRect::MakeRectXY(srcSpaceScaledRect, casterCornerRadius * scale, - casterCornerRadius * scale); - } - - SkPoint center = SkPoint::Make(srcSpaceSpotRRect.rect().centerX(), - srcSpaceSpotRRect.rect().centerY()); - SkMatrix ctmInverse; - if (!canvas->getTotalMatrix().invert(&ctmInverse)) { - ALOGW("Matrix is degenerate. Will not render spot shadow!"); - return; - } - SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y); - ctmInverse.mapPoints(&lightPos2D, 1); - const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX), - zRatio*(center.fY - lightPos2D.fY)); - - SkAutoCanvasRestore acr(canvas, true); - canvas->translate(spotOffset.fX, spotOffset.fY); - - SkRect devSpaceScaledRect; - canvas->getTotalMatrix().mapRect(&devSpaceScaledRect, srcSpaceScaledRect); - - SkRRect devSpaceSpotRRect; - if (isOval) { - devSpaceSpotRRect = SkRRect::MakeOval(devSpaceScaledRect); - } else { - const SkScalar devSpaceScaledCornerRadius = casterCornerRadius * scale * scaleFactor; - devSpaceSpotRRect = SkRRect::MakeRectXY(devSpaceScaledRect, devSpaceScaledCornerRadius, - devSpaceScaledCornerRadius); - } - - SkPaint paint; - paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, 0, 0, 0)); - - SkRect srcSpaceScaledClipRect = clipRR.rect(); - spotMatrix.mapRect(&srcSpaceScaledClipRect); - srcSpaceScaledClipRect.outset(SkScalarHalf(srcSpaceSpotRadius), - SkScalarHalf(srcSpaceSpotRadius)); - - SkRect devSpaceScaledClipRect; - canvas->getTotalMatrix().mapRect(&devSpaceScaledClipRect, srcSpaceScaledClipRect); - SkRRect devSpaceSpotClipRR; - if (clipRR.isOval()) { - devSpaceSpotClipRR = SkRRect::MakeOval(devSpaceScaledClipRect); - } else { - SkASSERT(clipRR.isRect()); - devSpaceSpotClipRR = SkRRect::MakeRect(devSpaceScaledClipRect); - } - - paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceSpotRRect, - devSpaceSpotClipRR, devSpaceSpotRadius)); - - SkRect cover = srcSpaceScaledClipRect; - if (!cover.intersect(srcSpaceSpotRRect.rect())) { - return; - } - - canvas->drawRect(cover, paint); - } -} - -/** - * @param casterRect the rectangle bounds of the RRect casting the shadow - * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow - * @param casterClipRect a rectangular clip that must be intersected with the - * shadow-casting RRect prior to casting the shadow - * @param revealClip a circular clip that must be interested with the castClipRect - * and the shadow-casting rect prior to casting the shadow - * @param ambientAlpha the maximum alpha value to use when drawing the ambient shadow - * @param spotAlpha the maximum alpha value to use when drawing the spot shadow - * @param casterAlpha the alpha value of the RRect casting the shadow (0.0-1.0 range) - * @param casterZValue the Z value of the caster RRect - * @param canvas the destination for the shadow draws - * - * We have special cases for 4 round rect shadow draws: - * 1) a RRect clipped by a reveal animation - * 2) a RRect clipped by a rectangle - * 3) an unclipped RRect with non-uniform scale - * 4) an unclipped RRect with uniform scale - * 1,2 and 4 require that the scale is uniform. - * 1 and 2 require that rects stay rects. - */ -static bool DrawShadowsAsRRects(const SkRect& casterRect, SkScalar casterCornerRadius, - const SkRect& casterClipRect, const RevealClip& revealClip, SkScalar ambientAlpha, - SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkCanvas* canvas) { - SkScalar scaleFactors[2]; - if (!canvas->getTotalMatrix().getMinMaxScales(scaleFactors)) { - ALOGW("Matrix is degenerate. Will not render shadow!"); - return false; - } - - // The casterClipRect will be empty when bounds clipping is disabled - bool casterIsClippedByRect = !casterClipRect.isEmpty(); - bool uniformScale = scaleFactors[0] == scaleFactors[1]; - - if (revealClip.willClip()) { - if (casterIsClippedByRect || !uniformScale || !canvas->getTotalMatrix().rectStaysRect()) { - return false; // Fall back to the slow path since PathOps are required - } - - const float revealRadius = revealClip.getRadius(); - SkRect revealClipRect = SkRect::MakeLTRB(revealClip.getX()-revealRadius, - revealClip.getY()-revealRadius, revealClip.getX()+revealRadius, - revealClip.getY()+revealRadius); - SkRRect revealClipRR = SkRRect::MakeOval(revealClipRect); - - DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, - casterZValue, scaleFactors[0], revealClipRR, canvas); - return true; - } - - if (casterIsClippedByRect) { - if (!uniformScale || !canvas->getTotalMatrix().rectStaysRect()) { - return false; // Fall back to the slow path since PathOps are required - } - - SkRRect casterClipRR = SkRRect::MakeRect(casterClipRect); - - DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, - casterZValue, scaleFactors[0], casterClipRR, canvas); - return true; - } - - // The fast path needs uniform scale - if (!uniformScale) { - SkRRect casterRR = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius); - DrawAmbientShadowGeneral(canvas, casterRR, casterZValue, ambientAlpha, - [&](const SkRRect& rrect, const SkPaint& paint) { - canvas->drawRRect(rrect, paint); - }); - DrawSpotShadowGeneral(canvas, casterRR, casterZValue, spotAlpha, - [&](const SkRRect& rrect, const SkPaint& paint) { - canvas->drawRRect(rrect, paint); - }); - return true; - } - - DrawRRectShadows(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, casterAlpha, - casterZValue, scaleFactors[0], canvas); - return true; -} - // copied from FrameBuilder::deferShadow void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster) { const RenderProperties& casterProperties = caster->getNodeProperties(); @@ -626,8 +135,8 @@ void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* return; } - float ambientAlpha = SkiaPipeline::getAmbientShadowAlpha()*casterAlpha; - float spotAlpha = SkiaPipeline::getSpotShadowAlpha()*casterAlpha; + float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha; + float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha; const float casterZValue = casterProperties.getZ(); const RevealClip& revealClip = casterProperties.getRevealClip(); @@ -659,19 +168,7 @@ void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* hwuiMatrix.copyTo(shadowMatrix); canvas->concat(shadowMatrix); - const Outline& casterOutline = casterProperties.getOutline(); - Rect possibleRect; - float radius; - if (casterOutline.getAsRoundRect(&possibleRect, &radius)) { - if (DrawShadowsAsRRects(possibleRect.toSkRect(), radius, casterClipRect, revealClip, - ambientAlpha, spotAlpha, casterAlpha, casterZValue, canvas)) { - return; - } - } - - // Hard cases and calls to general shadow code const SkPath* casterOutlinePath = casterProperties.getOutline().getPath(); - // holds temporary SkPath to store the result of intersections SkPath tmpPath; const SkPath* casterPath = casterOutlinePath; @@ -691,16 +188,11 @@ void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath); casterPath = &tmpPath; } - - DrawAmbientShadowGeneral(canvas, *casterPath, casterZValue, ambientAlpha, - [&](const SkPath& path, const SkPaint& paint) { - canvas->drawPath(path, paint); - }); - - DrawSpotShadowGeneral(canvas, *casterPath, casterZValue, spotAlpha, - [&](const SkPath& path, const SkPaint& paint) { - canvas->drawPath(path, paint); - }); + const Vector3 lightPos = SkiaPipeline::getLightCenter(); + SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z); + SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos, + SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK, + casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0); } }; // namespace skiapipeline |