aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xbench/ShadowBench.cpp5
-rw-r--r--include/core/SkPicture.h3
-rw-r--r--include/private/SkShadowFlags.h2
-rw-r--r--include/utils/SkShadowUtils.h109
-rw-r--r--src/core/SkColorSpaceXformCanvas.cpp3
-rw-r--r--src/core/SkDrawShadowInfo.h5
-rw-r--r--src/core/SkPicturePlayback.cpp13
-rw-r--r--src/core/SkPictureRecord.cpp5
-rw-r--r--src/core/SkReadBuffer.h1
-rw-r--r--src/gpu/GrRenderTargetContext.cpp31
-rw-r--r--src/gpu/GrRenderTargetContext.h2
-rw-r--r--src/gpu/SkGpuDevice.cpp3
-rw-r--r--src/utils/SkShadowUtils.cpp105
-rw-r--r--tests/ShadowTest.cpp5
14 files changed, 145 insertions, 147 deletions
diff --git a/bench/ShadowBench.cpp b/bench/ShadowBench.cpp
index f329664fb2..e454abd3a4 100755
--- a/bench/ShadowBench.cpp
+++ b/bench/ShadowBench.cpp
@@ -65,9 +65,8 @@ protected:
fRec.fZPlaneParams = SkPoint3::Make(0, 0, kElevation);
fRec.fLightPos = SkPoint3::Make(270, 0, 600);
fRec.fLightRadius = 800;
- fRec.fAmbientAlpha = 0.1f;
- fRec.fSpotAlpha = 0.25f;
- fRec.fColor = SK_ColorBLACK;
+ fRec.fAmbientColor = 0x19000000;
+ fRec.fSpotColor = 0x40000000;
fRec.fFlags = 0;
if (fTransparent) {
fRec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag;
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index b75e9fceff..4887db928f 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -159,10 +159,11 @@ private:
// V58: No more 2pt conical flipping.
// V59: No more LocalSpace option on PictureImageFilter
// V60: Remove flags in picture header
+ // V61: Change SkDrawPictureRec to take two colors rather than two alphas
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 56; // august 2017
- static const uint32_t CURRENT_PICTURE_VERSION = 60;
+ static const uint32_t CURRENT_PICTURE_VERSION = 61;
static bool IsValidPictInfo(const SkPictInfo& info);
static sk_sp<SkPicture> Forwardport(const SkPictInfo&,
diff --git a/include/private/SkShadowFlags.h b/include/private/SkShadowFlags.h
index 9f3dd6ab88..de035531e6 100644
--- a/include/private/SkShadowFlags.h
+++ b/include/private/SkShadowFlags.h
@@ -16,7 +16,7 @@ enum SkShadowFlags {
kTransparentOccluder_ShadowFlag = 0x01,
/** Don't try to use analytic shadows. */
kGeometricOnly_ShadowFlag = 0x02,
- /** Disable use of tonal values when applying color */
+ /** Disable use of tonal values when applying color (deprecated) */
kDisableTonalColor_ShadowFlag = 0x04,
/** mask for all shadow flags */
kAll_ShadowFlag = 0x07
diff --git a/include/utils/SkShadowUtils.h b/include/utils/SkShadowUtils.h
index 9550a925b9..3eca398fb1 100644
--- a/include/utils/SkShadowUtils.h
+++ b/include/utils/SkShadowUtils.h
@@ -31,23 +31,62 @@ public:
* @param lightPos The 3D position of the light relative to the canvas plane. This is
* independent of the canvas's current matrix.
* @param lightRadius The radius of the disc light.
+ * @param ambientColor The color of the ambient shadow.
+ * @param spotColor The color of the spot shadow.
+ * @param flags Options controlling opaque occluder optimizations and shadow appearance. See
+ * SkShadowFlags.
+ */
+ static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkColor ambientColor, SkColor spotColor,
+ uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
+
+ /**
+ * Deprecated version that uses one color and two alphas, and supports tonal color.
+ *
+ * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
+ * light. The shadow may be cached, depending on the path type and canvas matrix. If the
+ * matrix is perspective or the path is volatile, it will not be cached.
+ *
+ * @param canvas The canvas on which to draw the shadows.
+ * @param path The occluder used to generate the shadows.
+ * @param zPlaneParams Values for the plane function which returns the Z offset of the
+ * occluder from the canvas based on local x and y values (the current matrix is not applied).
+ * @param lightPos The 3D position of the light relative to the canvas plane. This is
+ * independent of the canvas's current matrix.
+ * @param lightRadius The radius of the disc light.
* @param ambientAlpha The maximum alpha of the ambient shadow.
* @param spotAlpha The maxium alpha of the spot shadow.
* @param color The shadow color.
* @param flags Options controlling opaque occluder optimizations and shadow appearance. See
* SkShadowFlags.
*/
- static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
+ static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlane,
const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
SkScalar spotAlpha, SkColor color,
- uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
+ uint32_t flags = SkShadowFlags::kNone_ShadowFlag) {
+ SkColor ambientColor;
+ SkColor spotColor;
+ if (flags & SkShadowFlags::kDisableTonalColor_ShadowFlag) {
+ ambientColor = SkColorSetARGB(ambientAlpha*SkColorGetA(color), SkColorGetR(color),
+ SkColorGetG(color), SkColorGetB(color));
+ spotColor = SkColorSetARGB(spotAlpha*SkColorGetA(color), SkColorGetR(color),
+ SkColorGetG(color), SkColorGetB(color));
+ } else {
+ SkColor inAmbient = SkColorSetA(color, ambientAlpha*SkColorGetA(color));
+ SkColor inSpot = SkColorSetA(color, spotAlpha*SkColorGetA(color));
+ ComputeTonalColors(inAmbient, inSpot, &ambientColor, &spotColor);
+ }
- /**
+ DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientColor, spotColor, flags);
+ }
+
+ /**
+ * Deprecated version with height value (to be removed when Flutter is updated).
+ *
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
* light.
*
- * Deprecated version with height value (to be removed when Flutter is updated).
- *
* @param canvas The canvas on which to draw the shadows.
* @param path The occluder used to generate the shadows.
* @param occluderHeight The vertical offset of the occluder from the canvas. This is
@@ -70,56 +109,16 @@ public:
color, flags);
}
- /**
- * Helper routine to compute scale alpha values for one-pass tonal alpha.
- *
- * The final color we want to emulate is generated by rendering a color shadow (C_rgb) using an
- * alpha computed from the color's luminance (C_a), and then a black shadow with alpha (S_a)
- * which is an adjusted value of 'a'. Assuming SrcOver, a background color of B_rgb, and
- * ignoring edge falloff, this becomes
- *
- * (C_a - S_a*C_a)*C_rgb + (1 - (S_a + C_a - S_a*C_a))*B_rgb
- *
- * Since we use premultiplied alpha, this means we can scale the color by (C_a - S_a*C_a) and
- * set the alpha to (S_a + C_a - S_a*C_a).
- *
- * @param r Red value of color
- * @param g Green value of color
- * @param b Blue value of color
- * @param a Alpha value of color
- * @param colorScale Factor to scale color values by
- * @param tonalAlpha Value to set alpha to
- */
- static inline void ComputeTonalColorParams(SkScalar r, SkScalar g, SkScalar b, SkScalar a,
- SkScalar* colorScale, SkScalar* tonalAlpha) {
- SkScalar max = SkTMax(SkTMax(r, g), b);
- SkScalar min = SkTMin(SkTMin(r, g), b);
- SkScalar luminance = 0.5f*(max + min);
-
- // We compute a color alpha value based on the luminance of the color, scaled by an
- // adjusted alpha value. We want the following properties to match the UX examples
- // (assuming a = 0.25) and to ensure that we have reasonable results when the color
- // is black and/or the alpha is 0:
- // f(0, a) = 0
- // f(luminance, 0) = 0
- // f(1, 0.25) = .5
- // f(0.5, 0.25) = .4
- // f(1, 1) = 1
- // The following functions match this as closely as possible.
- SkScalar alphaAdjust = (2.6f + (-2.66667f + 1.06667f*a)*a)*a;
- SkScalar colorAlpha = (3.544762f + (-4.891428f + 2.3466f*luminance)*luminance)*luminance;
- colorAlpha = SkTPin(alphaAdjust*colorAlpha, 0.0f, 1.0f);
-
- // Similarly, we set the greyscale alpha based on luminance and alpha so that
- // f(0, a) = a
- // f(luminance, 0) = 0
- // f(1, 0.25) = 0.15
- SkScalar greyscaleAlpha = SkTPin(a*(1 - 0.4f*luminance), 0.0f, 1.0f);
-
- *colorScale = colorAlpha*(SK_Scalar1 - greyscaleAlpha);
- *tonalAlpha = *colorScale + greyscaleAlpha;
- }
-
+ /**
+ * Helper routine to compute color values for one-pass tonal alpha.
+ *
+ * @param inAmbientColor Original ambient color
+ * @param inSpotColor Original spot color
+ * @param outAmbientColor Modified ambient color
+ * @param outSpotColor Modified spot color
+ */
+ static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor,
+ SkColor* outAmbientColor, SkColor* outSpotColor);
};
#endif
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp
index db5642df00..bbcb138858 100644
--- a/src/core/SkColorSpaceXformCanvas.cpp
+++ b/src/core/SkColorSpaceXformCanvas.cpp
@@ -238,7 +238,8 @@ public:
}
void onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) override {
SkDrawShadowRec newRec(rec);
- newRec.fColor = fXformer->apply(rec.fColor);
+ newRec.fAmbientColor = fXformer->apply(rec.fAmbientColor);
+ newRec.fSpotColor = fXformer->apply(rec.fSpotColor);
fTarget->private_draw_shadow_rec(path, newRec);
}
void onDrawPicture(const SkPicture* pic,
diff --git a/src/core/SkDrawShadowInfo.h b/src/core/SkDrawShadowInfo.h
index a08256b8cd..47799e5c4a 100644
--- a/src/core/SkDrawShadowInfo.h
+++ b/src/core/SkDrawShadowInfo.h
@@ -20,9 +20,8 @@ struct SkDrawShadowRec {
SkPoint3 fZPlaneParams;
SkPoint3 fLightPos;
SkScalar fLightRadius;
- SkScalar fAmbientAlpha;
- SkScalar fSpotAlpha;
- SkColor fColor;
+ SkColor fAmbientColor;
+ SkColor fSpotColor;
uint32_t fFlags;
};
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 9a57816a20..eee38c49fb 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -579,9 +579,16 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
reader->readPoint3(&rec.fZPlaneParams);
reader->readPoint3(&rec.fLightPos);
rec.fLightRadius = reader->readScalar();
- rec.fAmbientAlpha = reader->readScalar();
- rec.fSpotAlpha = reader->readScalar();
- rec.fColor = reader->read32();
+ if (reader->isVersionLT(SkReadBuffer::kTwoColorDrawShadow_Version)) {
+ SkScalar ambientAlpha = reader->readScalar();
+ SkScalar spotAlpha = reader->readScalar();
+ SkColor color = reader->read32();
+ rec.fAmbientColor = SkColorSetA(color, SkColorGetA(color)*ambientAlpha);
+ rec.fSpotColor = SkColorSetA(color, SkColorGetA(color)*spotAlpha);
+ } else {
+ rec.fAmbientColor = reader->read32();
+ rec.fSpotColor = reader->read32();
+ }
rec.fFlags = reader->read32();
BREAK_ON_READ_ERROR(reader);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5a3e8be2dd..d6d23074fd 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -795,9 +795,8 @@ void SkPictureRecord::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec&
fWriter.writePoint3(rec.fZPlaneParams);
fWriter.writePoint3(rec.fLightPos);
fWriter.writeScalar(rec.fLightRadius);
- fWriter.writeScalar(rec.fAmbientAlpha);
- fWriter.writeScalar(rec.fSpotAlpha);
- fWriter.write32(rec.fColor);
+ fWriter.write32(rec.fAmbientColor);
+ fWriter.write32(rec.fSpotColor);
fWriter.write32(rec.fFlags);
this->validate(initialOffset, size);
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 65ec8364fe..ff4b1671dd 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -77,6 +77,7 @@ public:
k2PtConicalNoFlip_Version = 58,
kRemovePictureImageFilterLocalSpace = 59,
kRemoveHeaderFlags_Version = 60,
+ kTwoColorDrawShadow_Version = 61,
};
/**
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 42a4fddc52..d86bf80d63 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -943,7 +943,6 @@ static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
}
bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
- GrColor color4ub,
const SkMatrix& viewMatrix,
const SkPath& path,
const SkDrawShadowRec& rec) {
@@ -998,11 +997,9 @@ bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
viewMatrix[SkMatrix::kMSkewX] * viewMatrix[SkMatrix::kMSkewX]);
SkScalar occluderHeight = rec.fZPlaneParams.fZ;
- GrColor4f color = GrColor4f::FromGrColor(color4ub);
bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
- bool tonalColor = !SkToBool(rec.fFlags & SkShadowFlags::kDisableTonalColor_ShadowFlag);
- if (rec.fAmbientAlpha > 0) {
+ if (SkColorGetA(rec.fAmbientColor) > 0) {
SkScalar devSpaceInsetWidth = SkDrawShadowMetrics::AmbientBlurRadius(occluderHeight);
const SkScalar umbraRecipAlpha = SkDrawShadowMetrics::AmbientRecipAlpha(occluderHeight);
const SkScalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;
@@ -1020,13 +1017,7 @@ bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
ambientRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
}
- GrColor ambientColor;
- if (tonalColor) {
- // with tonal color, the color only applies to the spot shadow
- ambientColor = GrColorPackRGBA(0, 0, 0, 255.999f*rec.fAmbientAlpha);
- } else {
- ambientColor = color.mulByScalar(rec.fAmbientAlpha).toGrColor();
- }
+ GrColor ambientColor = SkColorToPremulGrColor(rec.fAmbientColor);
if (transparent) {
// set a large inset to force a fill
devSpaceInsetWidth = ambientRRect.width();
@@ -1044,7 +1035,7 @@ bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
this->addDrawOp(clip, std::move(op));
}
- if (rec.fSpotAlpha > 0) {
+ if (SkColorGetA(rec.fSpotColor) > 0) {
SkScalar devSpaceSpotBlur;
SkScalar spotScale;
SkVector spotOffset;
@@ -1129,21 +1120,7 @@ bool GrRenderTargetContext::drawFastShadow(const GrClip& clip,
spotShadowRRect = SkRRect::MakeRectXY(outsetRect, outsetRad, outsetRad);
}
- GrColor spotColor;
- if (tonalColor) {
- SkScalar colorScale;
- SkScalar tonalAlpha;
- SkShadowUtils::ComputeTonalColorParams(color.fRGBA[0], color.fRGBA[1],
- color.fRGBA[2], color.fRGBA[3]*rec.fSpotAlpha,
- &colorScale, &tonalAlpha);
- color.fRGBA[0] *= colorScale;
- color.fRGBA[1] *= colorScale;
- color.fRGBA[2] *= colorScale;
- color.fRGBA[3] = tonalAlpha;
- spotColor = color.toGrColor();
- } else {
- spotColor = color.mulByScalar(rec.fSpotAlpha).toGrColor();
- }
+ GrColor spotColor = SkColorToPremulGrColor(rec.fSpotColor);
std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(spotColor, viewMatrix,
spotShadowRRect,
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 47cd922596..6e0c6745fd 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -172,13 +172,11 @@ public:
* Use a fast method to render the ambient and spot shadows for a path.
* Will return false if not possible for the given path.
*
- * @param color shadow color.
* @param viewMatrix transformation matrix
* @param path the path to shadow
* @param rec parameters for shadow rendering
*/
bool drawFastShadow(const GrClip&,
- GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const SkDrawShadowRec& rec);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index a781e53db6..8d6e55c1f6 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1586,8 +1586,7 @@ void SkGpuDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawShadow", fContext.get());
- GrColor color = SkColorToPremulGrColor(rec.fColor);
- if (!fRenderTargetContext->drawFastShadow(this->clip(), color, this->ctm(), path, rec)) {
+ if (!fRenderTargetContext->drawFastShadow(this->clip(), this->ctm(), path, rec)) {
// failed to find an accelerated case
this->INHERITED::drawShadow(path, rec);
}
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index bacc51a49c..12f95ee120 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -458,32 +458,65 @@ static SkPoint3 map(const SkMatrix& m, const SkPoint3& pt) {
return result;
}
-static SkColor compute_render_color(SkColor color, float alpha, bool useTonalColor) {
- if (useTonalColor) {
- SkScalar colorScale;
- SkScalar tonalAlpha;
- SkColor4f color4f = SkColor4f::FromColor(color);
- SkShadowUtils::ComputeTonalColorParams(color4f.fR,
- color4f.fG,
- color4f.fB,
- color4f.fA*alpha,
- &colorScale, &tonalAlpha);
- // After pre-multiplying, we want the alpha to be scaled by tonalAlpha, and
- // the color scaled by colorScale. This scale factor gives that.
- SkScalar unPremulScale = colorScale / tonalAlpha;
-
- return SkColorSetARGB(tonalAlpha*255.999f, unPremulScale*SkColorGetR(color),
- unPremulScale*SkColorGetG(color), unPremulScale*SkColorGetB(color));
- }
-
- return SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
- SkColorGetG(color), SkColorGetB(color));
+void SkShadowUtils::ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor,
+ SkColor* outAmbientColor, SkColor* outSpotColor) {
+ // For tonal color we only compute color values for the spot shadow.
+ // The ambient shadow is greyscale only.
+
+ // Ambient
+ *outAmbientColor = SkColorSetARGB(SkColorGetA(inAmbientColor), 0, 0, 0);
+
+ // Spot
+ int spotR = SkColorGetR(inSpotColor);
+ int spotG = SkColorGetG(inSpotColor);
+ int spotB = SkColorGetB(inSpotColor);
+ int max = SkTMax(SkTMax(spotR, spotG), spotB);
+ int min = SkTMin(SkTMin(spotR, spotG), spotB);
+ SkScalar luminance = 0.5f*(max + min)/255.f;
+ SkScalar origA = SkColorGetA(inSpotColor)/255.f;
+
+ // We compute a color alpha value based on the luminance of the color, scaled by an
+ // adjusted alpha value. We want the following properties to match the UX examples
+ // (assuming a = 0.25) and to ensure that we have reasonable results when the color
+ // is black and/or the alpha is 0:
+ // f(0, a) = 0
+ // f(luminance, 0) = 0
+ // f(1, 0.25) = .5
+ // f(0.5, 0.25) = .4
+ // f(1, 1) = 1
+ // The following functions match this as closely as possible.
+ SkScalar alphaAdjust = (2.6f + (-2.66667f + 1.06667f*origA)*origA)*origA;
+ SkScalar colorAlpha = (3.544762f + (-4.891428f + 2.3466f*luminance)*luminance)*luminance;
+ colorAlpha = SkTPin(alphaAdjust*colorAlpha, 0.0f, 1.0f);
+
+ // Similarly, we set the greyscale alpha based on luminance and alpha so that
+ // f(0, a) = a
+ // f(luminance, 0) = 0
+ // f(1, 0.25) = 0.15
+ SkScalar greyscaleAlpha = SkTPin(origA*(1 - 0.4f*luminance), 0.0f, 1.0f);
+
+ // The final color we want to emulate is generated by rendering a color shadow (C_rgb) using an
+ // alpha computed from the color's luminance (C_a), and then a black shadow with alpha (S_a)
+ // which is an adjusted value of 'a'. Assuming SrcOver, a background color of B_rgb, and
+ // ignoring edge falloff, this becomes
+ //
+ // (C_a - S_a*C_a)*C_rgb + (1 - (S_a + C_a - S_a*C_a))*B_rgb
+ //
+ // Assuming premultiplied alpha, this means we scale the color by (C_a - S_a*C_a) and
+ // set the alpha to (S_a + C_a - S_a*C_a).
+ SkScalar colorScale = colorAlpha*(SK_Scalar1 - greyscaleAlpha);
+ SkScalar tonalAlpha = colorScale + greyscaleAlpha;
+ SkScalar unPremulScale = colorScale / tonalAlpha;
+ *outSpotColor = SkColorSetARGB(tonalAlpha*255.999f,
+ unPremulScale*spotR,
+ unPremulScale*spotG,
+ unPremulScale*spotB);
}
// Draw an offset spot shadow and outlining ambient shadow for the given path.
void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
const SkPoint3& devLightPos, SkScalar lightRadius,
- SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
+ SkColor ambientColor, SkColor spotColor,
uint32_t flags) {
SkMatrix inverse;
if (!canvas->getTotalMatrix().invert(&inverse)) {
@@ -495,9 +528,8 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
rec.fZPlaneParams = zPlaneParams;
rec.fLightPos = { pt.fX, pt.fY, devLightPos.fZ };
rec.fLightRadius = lightRadius;
- rec.fAmbientAlpha = SkScalarToFloat(ambientAlpha);
- rec.fSpotAlpha = SkScalarToFloat(spotAlpha);
- rec.fColor = color;
+ rec.fAmbientColor = ambientColor;
+ rec.fSpotColor = spotColor;
rec.fFlags = flags;
canvas->private_draw_shadow_rec(path, rec);
@@ -519,22 +551,12 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
bool tiltZPlane = tilted(rec.fZPlaneParams);
bool transparent = SkToBool(rec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
bool uncached = tiltZPlane || path.isVolatile();
- bool useTonalColor = !SkToBool(rec.fFlags & kDisableTonalColor_ShadowFlag);
- SkColor color = rec.fColor;
SkPoint3 zPlaneParams = rec.fZPlaneParams;
SkPoint3 devLightPos = map(viewMatrix, rec.fLightPos);
float lightRadius = rec.fLightRadius;
- float ambientAlpha = rec.fAmbientAlpha;
- if (ambientAlpha > 0) {
- ambientAlpha = SkTMin(ambientAlpha, 1.f);
- SkColor renderColor;
- if (useTonalColor) {
- renderColor = compute_render_color(SK_ColorBLACK, ambientAlpha, false);
- } else {
- renderColor = compute_render_color(color, ambientAlpha, false);
- }
+ if (SkColorGetA(rec.fAmbientColor) > 0) {
if (uncached) {
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeAmbient(path, viewMatrix,
zPlaneParams,
@@ -544,7 +566,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
// Run the vertex color through a GaussianColorFilter and then modulate the
// grayscale result of that against our 'color' param.
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
- SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
+ SkColorFilter::MakeModeFilter(rec.fAmbientColor, SkBlendMode::kModulate),
SkGaussianColorFilter::Make()));
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
}
@@ -559,14 +581,11 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
factory.fOffset.fY = viewMatrix.getTranslateY();
}
- draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
+ draw_shadow(factory, drawVertsProc, shadowedPath, rec.fAmbientColor);
}
}
- float spotAlpha = rec.fSpotAlpha;
- if (spotAlpha > 0) {
- spotAlpha = SkTMin(spotAlpha, 1.f);
- SkColor renderColor = compute_render_color(color, spotAlpha, useTonalColor);
+ if (SkColorGetA(rec.fSpotColor) > 0) {
if (uncached) {
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeSpot(path, viewMatrix,
zPlaneParams,
@@ -577,7 +596,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
// Run the vertex color through a GaussianColorFilter and then modulate the
// grayscale result of that against our 'color' param.
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
- SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
+ SkColorFilter::MakeModeFilter(rec.fSpotColor, SkBlendMode::kModulate),
SkGaussianColorFilter::Make()));
this->drawVertices(vertices.get(), SkBlendMode::kModulate, paint);
}
@@ -627,7 +646,7 @@ void SkBaseDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
break;
}
#endif
- draw_shadow(factory, drawVertsProc, shadowedPath, renderColor);
+ draw_shadow(factory, drawVertsProc, shadowedPath, rec.fSpotColor);
}
}
}
diff --git a/tests/ShadowTest.cpp b/tests/ShadowTest.cpp
index 8a921d8bc8..90c1d8ffcc 100644
--- a/tests/ShadowTest.cpp
+++ b/tests/ShadowTest.cpp
@@ -65,9 +65,8 @@ void check_xformed_bounds(skiatest::Reporter* reporter, const SkPath& path, cons
SkPoint3::Make(0, 0, 4),
SkPoint3::Make(100, 0, 600),
800.f,
- 0.035f,
- 0.25f,
- SK_ColorBLACK,
+ 0x08000000,
+ 0x40000000,
0
};
SkRect bounds;