38#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
60#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
63uint64_t resource_cache_shared_id() {
64 return 0x2020776f64616873llu;
68struct AmbientVerticesFactory {
73 bool isCompatible(
const AmbientVerticesFactory& that,
SkVector* translate)
const {
74 if (fOccluderHeight != that.fOccluderHeight || fTransparent != that.fTransparent) {
77 *translate = that.fOffset;
96struct SpotVerticesFactory {
97 enum class OccluderType {
102 kPointOpaquePartialUmbra,
108 kDirectionalTransparent,
116 OccluderType fOccluderType;
118 bool isCompatible(
const SpotVerticesFactory& that,
SkVector* translate)
const {
119 if (fOccluderHeight != that.fOccluderHeight || fDevLightPos.
fZ != that.fDevLightPos.fZ ||
120 fLightRadius != that.fLightRadius || fOccluderType != that.fOccluderType) {
123 switch (fOccluderType) {
124 case OccluderType::kPointTransparent:
125 case OccluderType::kPointOpaqueNoUmbra:
128 *translate = that.fOffset;
130 case OccluderType::kPointOpaquePartialUmbra:
133 if (fOffset == that.fOffset) {
134 translate->
set(0, 0);
138 case OccluderType::kDirectional:
139 case OccluderType::kDirectionalTransparent:
140 *translate = that.fOffset - fOffset;
143 SK_ABORT(
"Uninitialized occluder type?");
148 bool transparent = fOccluderType == OccluderType::kPointTransparent ||
149 fOccluderType == OccluderType::kDirectionalTransparent;
150 bool directional = fOccluderType == OccluderType::kDirectional ||
151 fOccluderType == OccluderType::kDirectionalTransparent;
154 translate->
set(0, 0);
157 }
else if (ctm.
hasPerspective() || OccluderType::kPointOpaquePartialUmbra == fOccluderType) {
158 translate->
set(0, 0);
166 SkPoint devCenter(fLocalCenter);
167 noTrans.mapPoints(&devCenter, 1);
169 *translate = fOffset;
171 centerLightPos, fLightRadius, transparent,
false);
182class CachedTessellations :
public SkRefCnt {
184 size_t size()
const {
return fAmbientSet.size() + fSpotSet.size(); }
188 return fAmbientSet.find(ambient,
matrix, translate);
193 return fAmbientSet.add(devPath, ambient,
matrix, translate);
198 return fSpotSet.find(spot,
matrix, translate);
203 return fSpotSet.add(devPath, spot,
matrix, translate);
207 template <
typename FACTORY,
int MAX_ENTRIES>
210 size_t size()
const {
return fSize; }
214 for (
int i = 0;
i < MAX_ENTRIES; ++
i) {
215 if (fEntries[
i].fFactory.isCompatible(factory, translate)) {
217 if (
matrix.hasPerspective() ||
m.hasPerspective()) {
221 }
else if (
matrix.getScaleX() !=
m.getScaleX() ||
222 matrix.getSkewX() !=
m.getSkewX() ||
223 matrix.getScaleY() !=
m.getScaleY() ||
224 matrix.getSkewY() !=
m.getSkewY()) {
227 return fEntries[
i].fVertices;
240 if (
fCount < MAX_ENTRIES) {
243 i = fRandom.nextULessThan(MAX_ENTRIES);
244 fSize -= fEntries[
i].fVertices->approximateSize();
246 fEntries[
i].fFactory = factory;
247 fEntries[
i].fVertices = vertices;
259 Entry fEntries[MAX_ENTRIES];
265 Set<AmbientVerticesFactory, 4> fAmbientSet;
266 Set<SpotVerticesFactory, 4> fSpotSet;
277 : fTessellations(
std::move(tessellations)) {
278 fKey.reset(
new uint8_t[
key.size()]);
279 memcpy(fKey.get(), &
key,
key.size());
282 const Key& getKey()
const override {
286 size_t bytesUsed()
const override {
return fTessellations->
size(); }
288 const char* getCategory()
const override {
return "tessellated shadow masks"; }
292 template <
typename FACTORY>
295 return fTessellations->find(factory,
matrix, translate);
299 std::unique_ptr<uint8_t[]> fKey;
309template <
typename FACTORY>
311 FindContext(
const SkMatrix* viewMatrix,
const FACTORY* factory)
323 const FACTORY* fFactory;
331template <
typename FACTORY>
333 FindContext<FACTORY>* findContext = (FindContext<FACTORY>*)ctx;
334 const CachedTessellationsRec& rec =
static_cast<const CachedTessellationsRec&
>(baseRec);
335 findContext->fVertices =
336 rec.find(*findContext->fFactory, *findContext->fViewMatrix, &findContext->fTranslate);
337 if (findContext->fVertices) {
342 findContext->fTessellationsOnFailure = rec.refTessellations();
351#
if defined(SK_GANESH)
358#if defined(SK_GANESH)
360 int keyBytes()
const {
return fShapeForKey.unstyledKeySize() *
sizeof(uint32_t); }
361 void writeKey(
void*
key)
const {
362 fShapeForKey.writeUnstyledKey(
reinterpret_cast<uint32_t*
>(
key));
366 int keyBytes()
const {
return -1; }
367 void writeKey(
void*
key)
const {
SK_ABORT(
"Should never be called"); }
374#if defined(SK_GANESH)
380static void* kNamespace;
386 fKey.reset(
new uint8_t[
key.size()]);
387 memcpy(fKey.get(), &
key,
key.size());
400 void changed()
override {
404 std::unique_ptr<uint8_t[]> fKey;
411template <
typename FACTORY>
415 FindContext<FACTORY> context(&
path.viewMatrix(), &factory);
419 int keyDataBytes =
path.keyBytes();
420 if (keyDataBytes >= 0) {
423 path.writeKey((uint32_t*)(keyStorage.
begin() +
sizeof(*key)));
424 key->init(&kNamespace, resource_cache_shared_id(), keyDataBytes);
429 bool foundInCache =
SkToBool(context.fVertices);
431 vertices = std::move(context.fVertices);
437 if (context.fTessellationsOnFailure) {
438 tessellations = std::move(context.fTessellationsOnFailure);
440 tessellations.
reset(
new CachedTessellations());
442 vertices = tessellations->add(
path.path(), factory,
path.viewMatrix(),
443 &context.fTranslate);
447 auto rec =
new CachedTessellationsRec(*
key, std::move(tessellations));
451 vertices = factory.makeVertices(
path.path(),
path.viewMatrix(),
452 &context.fTranslate);
462 paint.setColorFilter(
467 context.fTranslate.fX, context.fTranslate.fY,
path.viewMatrix().hasPerspective());
505 SkScalar alphaAdjust = (2.6f + (-2.66667f + 1.06667f*origA)*origA)*origA;
506 SkScalar colorAlpha = (3.544762f + (-4.891428f + 2.3466f*luminance)*luminance)*luminance;
507 colorAlpha =
SkTPin(alphaAdjust*colorAlpha, 0.0f, 1.0f);
513 SkScalar greyscaleAlpha =
SkTPin(origA*(1 - 0.4f*luminance), 0.0f, 1.0f);
525 SkScalar tonalAlpha = colorScale + greyscaleAlpha;
526 SkScalar unPremulScale = colorScale / tonalAlpha;
530 unPremulScale*spotB);
542 if (!ctm.
invert(&inverse)) {
601#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
619 ShadowedPath shadowedPath(&
path, &viewMatrix);
625 bool uncached = tiltZPlane ||
path.isVolatile();
637 bool success =
false;
638#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
639 if (uncached && !useBlur) {
647 paint.setColorFilter(
662 if (!success && !useBlur) {
663 AmbientVerticesFactory factory;
664 factory.fOccluderHeight = zPlaneParams.
fZ;
665 factory.fTransparent = transparent;
667 factory.fOffset.set(0, 0);
681 path.transform(viewMatrix, &devSpacePath);
712 SkScalar blurRadius = 0.5f*devSpaceOutset*oneOverA;
721 bool respectCTM =
false;
728 bool success =
false;
729#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
730 if (uncached && !useBlur) {
733 devLightPos, lightRadius,
740 paint.setColorFilter(
755 if (!success && !useBlur) {
756 SpotVerticesFactory factory;
757 factory.fOccluderHeight = zPlaneParams.
fZ;
758 factory.fDevLightPos = devLightPos;
759 factory.fLightRadius = lightRadius;
762 factory.fLocalCenter =
center;
767 devLightPos.
fY, devLightPos.
fZ,
768 lightRadius, &radius, &
scale,
773 lightRadius, &radius, &
scale, &factory.fOffset);
779 SkTAbs(factory.fOffset.fX) > 0.5f*devBounds.
width() ||
784 factory.fOccluderType =
785 SpotVerticesFactory::OccluderType::kDirectionalTransparent;
787 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointTransparent;
789 }
else if (directional) {
790 factory.fOccluderType = SpotVerticesFactory::OccluderType::kDirectional;
791 }
else if (factory.fOffset.length()*
scale +
scale < radius) {
793 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointOpaqueNoUmbra;
794 }
else if (
path.isConvex()) {
795 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointOpaquePartialUmbra;
797 factory.fOccluderType = SpotVerticesFactory::OccluderType::kPointTransparent;
804#ifdef DEBUG_SHADOW_CHECKS
805 switch (factory.fOccluderType) {
806 case SpotVerticesFactory::OccluderType::kPointTransparent:
809 case SpotVerticesFactory::OccluderType::kPointOpaquePartialUmbra:
812 case SpotVerticesFactory::OccluderType::kPointOpaqueNoUmbra:
815 case SpotVerticesFactory::OccluderType::kDirectional:
816 case SpotVerticesFactory::OccluderType::kDirectionalTransparent:
830 viewMatrix, zPlaneParams,
831 path.getBounds(), directional,
832 &shadowMatrix, &radius)) {
840 bool respectCTM =
false;
static const int strokeWidth
#define SK_ABORT(message,...)
@ kNormal_SkBlurStyle
fuzzy inside and outside
#define SkColorGetR(color)
#define SkColorGetG(color)
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
constexpr SkColor SK_ColorBLACK
#define SkColorGetA(color)
#define SkColorGetB(color)
static bool SkIsFinite(T x, Pack... values)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
static bool tilted(const SkPoint3 &zPlaneParams)
static bool fill_shadow_rec(const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags, const SkMatrix &ctm, SkDrawShadowRec *rec)
static bool validate_rec(const SkDrawShadowRec &rec)
@ kDirectionalLight_ShadowFlag
@ kConcaveBlurOnly_ShadowFlag
@ kTransparentOccluder_ShadowFlag
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
static constexpr bool SkToBool(const T &x)
static SkScalar center(float pos0, float pos1)
int find(T *array, int N, T item)
static sk_sp< SkBlender > Mode(SkBlendMode mode)
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
void private_draw_shadow_rec(const SkPath &, const SkDrawShadowRec &)
SkMatrix getTotalMatrix() const
static sk_sp< SkColorFilter > MakeGaussian()
sk_sp< SkColorFilter > makeComposed(sk_sp< SkColorFilter > inner) const
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
virtual void drawVertices(const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool skipColorXform=false)=0
virtual void drawShadow(const SkPath &, const SkDrawShadowRec &)
const SkMatrix & localToDevice() const
virtual void drawPath(const SkPath &path, const SkPaint &paint, bool pathIsMutable=false)=0
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
static constexpr int kMTransY
vertical translation
static SkMatrix Translate(SkScalar dx, SkScalar dy)
SkScalar getTranslateY() const
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
bool invert(SkMatrix *inverse) const
static const SkMatrix & I()
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkScalar getTranslateX() const
@ kStrokeAndFill_Style
sets to stroke and fill geometry
static void AddGenIDChangeListener(const SkPath &path, sk_sp< SkIDChangeListener > listener)
SkPath & setIsVolatile(bool isVolatile)
static void Add(Rec *, void *payload=nullptr)
static bool Find(const Key &key, FindVisitor, void *context)
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)
static bool GetLocalBounds(const SkMatrix &ctm, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, uint32_t flags, SkRect *bounds)
static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor, SkColor *outAmbientColor, SkColor *outSpotColor)
size_t approximateSize() const
void reset(T *ptr=nullptr)
FlutterSemanticsFlag flags
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
bool GetSpotShadowTransform(const SkPoint3 &lightPos, SkScalar lightRadius, const SkMatrix &ctm, const SkPoint3 &zPlaneParams, const SkRect &pathBounds, bool directional, SkMatrix *shadowTransform, SkScalar *radius)
void GetLocalBounds(const SkPath &path, const SkDrawShadowRec &rec, const SkMatrix &ctm, SkRect *bounds)
SkScalar AmbientRecipAlpha(SkScalar height)
void GetDirectionalParams(SkScalar occluderZ, SkScalar lightX, SkScalar lightY, SkScalar lightZ, SkScalar lightRadius, SkScalar *blurRadius, SkScalar *scale, SkVector *translate)
SkScalar AmbientBlurRadius(SkScalar height)
void GetSpotParams(SkScalar occluderZ, SkScalar lightX, SkScalar lightY, SkScalar lightZ, SkScalar lightRadius, SkScalar *blurRadius, SkScalar *scale, SkVector *translate)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< SkVertices > MakeAmbient(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, bool transparent)
sk_sp< SkVertices > MakeSpot(const SkPath &path, const SkMatrix &ctm, const SkPoint3 &zPlane, const SkPoint3 &lightPos, SkScalar lightRadius, bool transparent, bool directional)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
void draw_shadow(SkCanvas *canvas, const SkPath &path, SkScalar height, SkColor color, SkPoint3 lightPos, SkScalar lightR, bool isAmbient, uint32_t flags)
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
static constexpr SkPoint Make(float x, float y)
void set(float x, float y)
constexpr float height() const
constexpr float width() const