Remove tonal color from DrawShadow internals
Bug: b/71719631 Change-Id: I676c34dfe5ea9b5e184ea53dd49a8b835d4e8cb6 Reviewed-on: https://skia-review.googlesource.com/95741 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
8bad7e01ba
commit
b1b80f7de4
@ -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;
|
||||
|
@ -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&,
|
||||
|
@ -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
|
||||
|
@ -20,6 +20,30 @@ class SkResourceCache;
|
||||
class SK_API SkShadowUtils {
|
||||
public:
|
||||
/**
|
||||
* 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 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.
|
||||
@ -37,17 +61,32 @@ public:
|
||||
* @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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
k2PtConicalNoFlip_Version = 58,
|
||||
kRemovePictureImageFilterLocalSpace = 59,
|
||||
kRemoveHeaderFlags_Version = 60,
|
||||
kTwoColorDrawShadow_Version = 61,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
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.
|
||||
|
||||
return SkColorSetARGB(tonalAlpha*255.999f, unPremulScale*SkColorGetR(color),
|
||||
unPremulScale*SkColorGetG(color), unPremulScale*SkColorGetB(color));
|
||||
}
|
||||
// Ambient
|
||||
*outAmbientColor = SkColorSetARGB(SkColorGetA(inAmbientColor), 0, 0, 0);
|
||||
|
||||
return SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
|
||||
SkColorGetG(color), SkColorGetB(color));
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user