Unify ShadowUtils interface
Bug: skia: Change-Id: I116bec82783d297e91ef061217b5e61f7ff16a76 Reviewed-on: https://skia-review.googlesource.com/16371 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
77ced29102
commit
37c5a96bbd
@ -12,24 +12,17 @@
|
|||||||
#include "SkShadowUtils.h"
|
#include "SkShadowUtils.h"
|
||||||
|
|
||||||
void draw_shadow(SkCanvas* canvas, const SkPath& path, int height, SkColor color, SkPoint3 lightPos,
|
void draw_shadow(SkCanvas* canvas, const SkPath& path, int height, SkColor color, SkPoint3 lightPos,
|
||||||
SkScalar lightR, bool isAmbient, uint32_t flags, SkResourceCache* cache) {
|
SkScalar lightR, bool isAmbient, uint32_t flags) {
|
||||||
SkScalar ambientAlpha = isAmbient ? .5f : 0.f;
|
SkScalar ambientAlpha = isAmbient ? .5f : 0.f;
|
||||||
SkScalar spotAlpha = isAmbient ? 0.f : .5f;
|
SkScalar spotAlpha = isAmbient ? 0.f : .5f;
|
||||||
SkShadowUtils::DrawShadow(canvas, path, height, lightPos, lightR, ambientAlpha, spotAlpha,
|
SkShadowUtils::DrawShadow(canvas, path, height, lightPos, lightR, ambientAlpha, spotAlpha,
|
||||||
color, flags, cache);
|
color, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr int kW = 800;
|
static constexpr int kW = 800;
|
||||||
static constexpr int kH = 800;
|
static constexpr int kH = 800;
|
||||||
|
|
||||||
DEF_SIMPLE_GM(shadow_utils, canvas, kW, kH) {
|
DEF_SIMPLE_GM(shadow_utils, canvas, kW, kH) {
|
||||||
// SkShadowUtils uses a cache of SkVertices meshes. The vertices are created in a local
|
|
||||||
// coordinate system and then translated when reused. The coordinate system depends on
|
|
||||||
// parameters to the generating draw. If other threads are hitting the cache while this GM is
|
|
||||||
// running then we may have different cache behavior leading to slight rendering differences.
|
|
||||||
// To avoid that we use our own isolated cache rather than the global cache.
|
|
||||||
SkResourceCache cache(1 << 20);
|
|
||||||
|
|
||||||
SkTArray<SkPath> paths;
|
SkTArray<SkPath> paths;
|
||||||
paths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
|
paths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
|
||||||
SkRRect oddRRect;
|
SkRRect oddRRect;
|
||||||
@ -70,10 +63,8 @@ DEF_SIMPLE_GM(shadow_utils, canvas, kW, kH) {
|
|||||||
|
|
||||||
canvas->save();
|
canvas->save();
|
||||||
canvas->concat(m);
|
canvas->concat(m);
|
||||||
draw_shadow(canvas, path, kHeight, SK_ColorRED, kLightPos, kLightR, true, flags,
|
draw_shadow(canvas, path, kHeight, SK_ColorRED, kLightPos, kLightR, true, flags);
|
||||||
&cache);
|
draw_shadow(canvas, path, kHeight, SK_ColorBLUE, kLightPos, kLightR, false, flags);
|
||||||
draw_shadow(canvas, path, kHeight, SK_ColorBLUE, kLightPos, kLightR, false, flags,
|
|
||||||
&cache);
|
|
||||||
|
|
||||||
// Draw the path outline in green on top of the ambient and spot shadows.
|
// Draw the path outline in green on top of the ambient and spot shadows.
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
|
@ -21,12 +21,14 @@ class SkShadowUtils {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
|
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
|
||||||
* light.
|
* 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 canvas The canvas on which to draw the shadows.
|
||||||
* @param path The occluder used to generate the shadows.
|
* @param path The occluder used to generate the shadows.
|
||||||
* @param occluderHeight The vertical offset of the occluder from the canvas. This is
|
* @param zPlaneParams Values for the plane function which returns the Z offset of the
|
||||||
* independent of the canvas's current matrix.
|
* occluder from the canvas based on local x and y values (the current matrix is not applied).
|
||||||
|
* If the canvas matrix is not perspective, then only zPlaneParams.fZ is used.
|
||||||
* @param lightPos The 3D position of the light relative to the canvas plane. This is
|
* @param lightPos The 3D position of the light relative to the canvas plane. This is
|
||||||
* independent of the canvas's current matrix.
|
* independent of the canvas's current matrix.
|
||||||
* @param lightRadius The radius of the disc light.
|
* @param lightRadius The radius of the disc light.
|
||||||
@ -35,20 +37,47 @@ public:
|
|||||||
* @param color The shadow color.
|
* @param color The shadow color.
|
||||||
* @param flags Options controlling opaque occluder optimizations and shadow appearance. See
|
* @param flags Options controlling opaque occluder optimizations and shadow appearance. See
|
||||||
* SkShadowFlags.
|
* SkShadowFlags.
|
||||||
* @param cache Used for testing purposes. Clients should pass nullptr (default).
|
|
||||||
*/
|
*/
|
||||||
|
static void DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
|
||||||
|
const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
|
||||||
|
SkScalar spotAlpha, SkColor color,
|
||||||
|
uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 Android and Flutter are 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
|
||||||
|
* independent of the canvas's current matrix.
|
||||||
|
* @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, SkScalar occluderHeight,
|
static void DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
|
||||||
const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
|
const SkPoint3& lightPos, SkScalar lightRadius, SkScalar ambientAlpha,
|
||||||
SkScalar spotAlpha, SkColor color,
|
SkScalar spotAlpha, SkColor color,
|
||||||
uint32_t flags = SkShadowFlags::kNone_ShadowFlag,
|
uint32_t flags = SkShadowFlags::kNone_ShadowFlag) {
|
||||||
SkResourceCache* cache = nullptr);
|
SkPoint3 zPlane = SkPoint3::Make(0, 0, occluderHeight);
|
||||||
|
DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
|
||||||
|
color, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||||
/**
|
/**
|
||||||
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
|
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
|
||||||
* light. Takes a function to vary the z value based on the local x and y position.
|
* light. Takes a function to vary the z value based on the local x and y position.
|
||||||
* This shadow will not be cached, as the assumption is that this will be used for animation.
|
* This shadow will not be cached, as the assumption is that this will be used for animation.
|
||||||
*
|
*
|
||||||
* Deprecated version with height functor (to be removed when Android is updated).
|
* Deprecated (to be removed when Android is updated).
|
||||||
*
|
*
|
||||||
* @param canvas The canvas on which to draw the shadows.
|
* @param canvas The canvas on which to draw the shadows.
|
||||||
* @param path The occluder used to generate the shadows.
|
* @param path The occluder used to generate the shadows.
|
||||||
@ -73,35 +102,10 @@ public:
|
|||||||
zPlane.fX = heightFunc(1, 0) - zPlane.fZ;
|
zPlane.fX = heightFunc(1, 0) - zPlane.fZ;
|
||||||
zPlane.fY = heightFunc(0, 1) - zPlane.fZ;
|
zPlane.fY = heightFunc(0, 1) - zPlane.fZ;
|
||||||
|
|
||||||
DrawUncachedShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
|
DrawShadow(canvas, path, zPlane, lightPos, lightRadius, ambientAlpha, spotAlpha,
|
||||||
color, flags);
|
color, flags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/**
|
|
||||||
* Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
|
|
||||||
* light. Uses a plane function to vary the z value based on the local x and y position.
|
|
||||||
* This shadow will not be cached, as the assumption is that this will be used for animation.
|
|
||||||
*
|
|
||||||
* @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 DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
|
|
||||||
const SkPoint3& zPlaneParams,
|
|
||||||
const SkPoint3& lightPos, SkScalar lightRadius,
|
|
||||||
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
|
||||||
uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -145,13 +145,9 @@ protected:
|
|||||||
if (fUseAlt) {
|
if (fUseAlt) {
|
||||||
flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
|
flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
|
||||||
}
|
}
|
||||||
//SkShadowUtils::DrawShadow(canvas, path,
|
SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
|
||||||
// zValue,
|
lightPos, lightWidth,
|
||||||
// lightPos, lightWidth,
|
ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
|
||||||
// ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
|
|
||||||
SkShadowUtils::DrawUncachedShadow(canvas, path, zPlaneParams,
|
|
||||||
lightPos, lightWidth,
|
|
||||||
ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
|
|
||||||
|
|
||||||
if (fShowObject) {
|
if (fShowObject) {
|
||||||
canvas->drawPath(path, paint);
|
canvas->drawPath(path, paint);
|
||||||
|
@ -126,16 +126,12 @@ protected:
|
|||||||
if (fUseAlt) {
|
if (fUseAlt) {
|
||||||
flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
|
flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
|
||||||
}
|
}
|
||||||
//SkShadowUtils::DrawShadow(canvas, path,
|
SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
|
||||||
// zValue,
|
lightPos, lightWidth,
|
||||||
// lightPos, lightWidth,
|
ambientAlpha, 0, SK_ColorRED, flags);
|
||||||
// ambientAlpha, spotAlpha, SK_ColorBLACK, flags);
|
SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
|
||||||
SkShadowUtils::DrawUncachedShadow(canvas, path, zPlaneParams,
|
lightPos, lightWidth,
|
||||||
lightPos, lightWidth,
|
0, spotAlpha, SK_ColorBLUE, flags);
|
||||||
ambientAlpha, 0, SK_ColorRED, flags);
|
|
||||||
SkShadowUtils::DrawUncachedShadow(canvas, path, zPlaneParams,
|
|
||||||
lightPos, lightWidth,
|
|
||||||
0, spotAlpha, SK_ColorBLUE, flags);
|
|
||||||
|
|
||||||
if (fShowObject) {
|
if (fShowObject) {
|
||||||
canvas->drawPath(path, paint);
|
canvas->drawPath(path, paint);
|
||||||
|
@ -441,8 +441,7 @@ static void* kNamespace;
|
|||||||
* they are first found in SkResourceCache.
|
* they are first found in SkResourceCache.
|
||||||
*/
|
*/
|
||||||
template <typename FACTORY>
|
template <typename FACTORY>
|
||||||
void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, SkColor color,
|
void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, SkColor color) {
|
||||||
SkResourceCache* cache) {
|
|
||||||
FindContext<FACTORY> context(&path.viewMatrix(), &factory);
|
FindContext<FACTORY> context(&path.viewMatrix(), &factory);
|
||||||
|
|
||||||
SkResourceCache::Key* key = nullptr;
|
SkResourceCache::Key* key = nullptr;
|
||||||
@ -453,11 +452,7 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
|
|||||||
key = new (keyStorage.begin()) SkResourceCache::Key();
|
key = new (keyStorage.begin()) SkResourceCache::Key();
|
||||||
path.writeKey((uint32_t*)(keyStorage.begin() + sizeof(*key)));
|
path.writeKey((uint32_t*)(keyStorage.begin() + sizeof(*key)));
|
||||||
key->init(&kNamespace, resource_cache_shared_id(), keyDataBytes);
|
key->init(&kNamespace, resource_cache_shared_id(), keyDataBytes);
|
||||||
if (cache) {
|
SkResourceCache::Find(*key, FindVisitor<FACTORY>, &context);
|
||||||
cache->find(*key, FindVisitor<FACTORY>, &context);
|
|
||||||
} else {
|
|
||||||
SkResourceCache::Find(*key, FindVisitor<FACTORY>, &context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_sp<SkVertices> vertices;
|
sk_sp<SkVertices> vertices;
|
||||||
@ -482,11 +477,7 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto rec = new CachedTessellationsRec(*key, std::move(tessellations));
|
auto rec = new CachedTessellationsRec(*key, std::move(tessellations));
|
||||||
if (cache) {
|
SkResourceCache::Add(rec);
|
||||||
cache->add(rec);
|
|
||||||
} else {
|
|
||||||
SkResourceCache::Add(rec);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vertices = factory.makeVertices(path.path(), path.viewMatrix());
|
vertices = factory.makeVertices(path.path(), path.viewMatrix());
|
||||||
if (!vertices) {
|
if (!vertices) {
|
||||||
@ -585,13 +576,13 @@ static SkColor compute_render_color(SkColor color, float alpha) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw an offset spot shadow and outlining ambient shadow for the given path.
|
// Draw an offset spot shadow and outlining ambient shadow for the given path.
|
||||||
void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
|
void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
|
||||||
const SkPoint3& devLightPos, SkScalar lightRadius,
|
const SkPoint3& devLightPos, SkScalar lightRadius,
|
||||||
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
||||||
uint32_t flags, SkResourceCache* cache) {
|
uint32_t flags) {
|
||||||
// try fast paths
|
// try fast paths
|
||||||
bool skipAnalytic = SkToBool(flags & SkShadowFlags::kGeometricOnly_ShadowFlag);
|
bool skipAnalytic = SkToBool(flags & SkShadowFlags::kGeometricOnly_ShadowFlag);
|
||||||
if (!skipAnalytic && draw_analytic_shadows(canvas, path, occluderHeight, devLightPos,
|
if (!skipAnalytic && draw_analytic_shadows(canvas, path, zPlaneParams.fZ, devLightPos,
|
||||||
lightRadius, ambientAlpha, spotAlpha, color,
|
lightRadius, ambientAlpha, spotAlpha, color,
|
||||||
flags)) {
|
flags)) {
|
||||||
return;
|
return;
|
||||||
@ -604,124 +595,63 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
|
|||||||
ShadowedPath shadowedPath(&path, &viewMatrix);
|
ShadowedPath shadowedPath(&path, &viewMatrix);
|
||||||
|
|
||||||
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
||||||
|
bool uncached = viewMatrix.hasPerspective() || path.isVolatile();
|
||||||
|
|
||||||
if (ambientAlpha > 0) {
|
if (ambientAlpha > 0) {
|
||||||
ambientAlpha = SkTMin(ambientAlpha, 1.f);
|
ambientAlpha = SkTMin(ambientAlpha, 1.f);
|
||||||
AmbientVerticesFactory factory;
|
if (uncached) {
|
||||||
factory.fOccluderHeight = occluderHeight;
|
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeAmbient(path, viewMatrix,
|
||||||
factory.fTransparent = transparent;
|
zPlaneParams,
|
||||||
|
transparent);
|
||||||
SkColor renderColor = compute_render_color(color, ambientAlpha);
|
SkColor renderColor = compute_render_color(color, ambientAlpha);
|
||||||
draw_shadow(factory, canvas, shadowedPath, renderColor, cache);
|
SkPaint paint;
|
||||||
}
|
// Run the vertex color through a GaussianColorFilter and then modulate the grayscale
|
||||||
|
// result of that against our 'color' param.
|
||||||
if (spotAlpha > 0) {
|
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
||||||
spotAlpha = SkTMin(spotAlpha, 1.f);
|
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
||||||
SpotVerticesFactory factory;
|
SkGaussianColorFilter::Make()));
|
||||||
float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
|
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
||||||
SkScalar radius = lightRadius * zRatio;
|
|
||||||
|
|
||||||
// Compute the scale and translation for the spot shadow.
|
|
||||||
SkScalar scale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
|
|
||||||
|
|
||||||
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
|
|
||||||
viewMatrix.mapPoints(¢er, 1);
|
|
||||||
factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
|
|
||||||
zRatio * (center.fY - devLightPos.fY));
|
|
||||||
factory.fOccluderHeight = occluderHeight;
|
|
||||||
factory.fDevLightPos = devLightPos;
|
|
||||||
factory.fLightRadius = lightRadius;
|
|
||||||
|
|
||||||
SkRRect rrect;
|
|
||||||
if (transparent) {
|
|
||||||
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
|
|
||||||
} else {
|
} else {
|
||||||
factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaque;
|
AmbientVerticesFactory factory;
|
||||||
if (shadowedPath.isRRect(&rrect)) {
|
factory.fOccluderHeight = zPlaneParams.fZ;
|
||||||
SkRRect devRRect;
|
factory.fTransparent = transparent;
|
||||||
if (rrect.transform(viewMatrix, &devRRect)) {
|
|
||||||
SkScalar s = 1.f - scale;
|
SkColor renderColor = compute_render_color(color, ambientAlpha);
|
||||||
SkScalar w = devRRect.width();
|
draw_shadow(factory, canvas, shadowedPath, renderColor);
|
||||||
SkScalar h = devRRect.height();
|
|
||||||
SkScalar hw = w / 2.f;
|
|
||||||
SkScalar hh = h / 2.f;
|
|
||||||
SkScalar umbraInsetX = s * hw + radius;
|
|
||||||
SkScalar umbraInsetY = s * hh + radius;
|
|
||||||
// The umbra is inset by radius along the diagonal, so adjust for that.
|
|
||||||
SkScalar d = 1.f / SkScalarSqrt(hw * hw + hh * hh);
|
|
||||||
umbraInsetX *= hw * d;
|
|
||||||
umbraInsetY *= hh * d;
|
|
||||||
if (umbraInsetX > hw || umbraInsetY > hh) {
|
|
||||||
// There is no umbra to occlude.
|
|
||||||
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
|
|
||||||
} else if (fabsf(factory.fOffset.fX) < umbraInsetX &&
|
|
||||||
fabsf(factory.fOffset.fY) < umbraInsetY) {
|
|
||||||
factory.fOccluderType =
|
|
||||||
SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra;
|
|
||||||
} else if (factory.fOffset.fX > w - umbraInsetX ||
|
|
||||||
factory.fOffset.fY > h - umbraInsetY) {
|
|
||||||
// There umbra is fully exposed, there is nothing to omit.
|
|
||||||
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (factory.fOccluderType == SpotVerticesFactory::OccluderType::kOpaque) {
|
|
||||||
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkColor renderColor = compute_render_color(color, spotAlpha);
|
|
||||||
draw_shadow(factory, canvas, shadowedPath, renderColor, cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw an offset spot shadow and outlining ambient shadow for the given path,
|
|
||||||
// without caching and using a function based on local position to compute the height.
|
|
||||||
void SkShadowUtils::DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
|
|
||||||
const SkPoint3& zPlaneParams,
|
|
||||||
const SkPoint3& lightPos, SkScalar lightRadius,
|
|
||||||
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
|
|
||||||
uint32_t flags) {
|
|
||||||
// try fast paths
|
|
||||||
bool skipAnalytic = SkToBool(flags & SkShadowFlags::kGeometricOnly_ShadowFlag);
|
|
||||||
if (!skipAnalytic && draw_analytic_shadows(canvas, path, zPlaneParams.fZ, lightPos,
|
|
||||||
lightRadius, ambientAlpha, spotAlpha, color,
|
|
||||||
flags)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SkAutoCanvasRestore acr(canvas, true);
|
|
||||||
SkMatrix viewMatrix = canvas->getTotalMatrix();
|
|
||||||
canvas->resetMatrix();
|
|
||||||
|
|
||||||
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
|
|
||||||
|
|
||||||
if (ambientAlpha > 0) {
|
|
||||||
ambientAlpha = SkTMin(ambientAlpha, 1.f);
|
|
||||||
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeAmbient(path, viewMatrix,
|
|
||||||
zPlaneParams, transparent);
|
|
||||||
SkColor renderColor = compute_render_color(color, ambientAlpha);
|
|
||||||
SkPaint paint;
|
|
||||||
// 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),
|
|
||||||
SkGaussianColorFilter::Make()));
|
|
||||||
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spotAlpha > 0) {
|
if (spotAlpha > 0) {
|
||||||
spotAlpha = SkTMin(spotAlpha, 1.f);
|
spotAlpha = SkTMin(spotAlpha, 1.f);
|
||||||
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeSpot(path, viewMatrix, zPlaneParams,
|
if (uncached) {
|
||||||
lightPos, lightRadius,
|
sk_sp<SkVertices> vertices = SkShadowTessellator::MakeSpot(path, viewMatrix,
|
||||||
transparent);
|
zPlaneParams,
|
||||||
SkColor renderColor = compute_render_color(color, spotAlpha);
|
devLightPos, lightRadius,
|
||||||
SkPaint paint;
|
transparent);
|
||||||
// Run the vertex color through a GaussianColorFilter and then modulate the grayscale
|
SkColor renderColor = compute_render_color(color, spotAlpha);
|
||||||
// result of that against our 'color' param.
|
SkPaint paint;
|
||||||
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
// Run the vertex color through a GaussianColorFilter and then modulate the grayscale
|
||||||
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
// result of that against our 'color' param.
|
||||||
SkGaussianColorFilter::Make()));
|
paint.setColorFilter(SkColorFilter::MakeComposeFilter(
|
||||||
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
SkColorFilter::MakeModeFilter(renderColor, SkBlendMode::kModulate),
|
||||||
|
SkGaussianColorFilter::Make()));
|
||||||
|
canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
|
||||||
|
} else {
|
||||||
|
SpotVerticesFactory factory;
|
||||||
|
SkScalar occluderHeight = zPlaneParams.fZ;
|
||||||
|
float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
|
||||||
|
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
|
||||||
|
viewMatrix.mapPoints(¢er, 1);
|
||||||
|
factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
|
||||||
|
zRatio * (center.fY - devLightPos.fY));
|
||||||
|
factory.fOccluderHeight = occluderHeight;
|
||||||
|
factory.fDevLightPos = devLightPos;
|
||||||
|
factory.fLightRadius = lightRadius;
|
||||||
|
// the only valid choice we have right now
|
||||||
|
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
|
||||||
|
|
||||||
|
SkColor renderColor = compute_render_color(color, spotAlpha);
|
||||||
|
draw_shadow(factory, canvas, shadowedPath, renderColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user