40class InvalidationController;
46static constexpr char gBulgeDisplacementSkSL[] =
47 "uniform shader u_layer;"
49 "uniform float2 u_center;"
50 "uniform float2 u_radius;"
51 "uniform float2 u_radius_inv;"
53 "uniform float u_rcpR;"
54 "uniform float u_rcpAsinInvR;"
55 "uniform float u_selector;"
61 "float2 displace_sph(float2 v) {"
62 "float arc_ratio = asin(length(v)*u_rcpR)*u_rcpAsinInvR;"
63 "return normalize(v)*arc_ratio - v;"
66 "float2 displace_exp(float2 v) {"
67 "return v*pow(dot(v,v),u_h) - v;"
70 "half2 displace(float2 v) {"
71 "float t = dot(v, v);"
75 "float2 d = displace_sph(v) + displace_exp(v);"
76 "return v + (d * u_selector);"
79 "half4 main(float2 xy) {"
83 "xy = (xy - u_center)*u_radius_inv;"
86 "xy = xy*u_radius + u_center;"
87 "return u_layer.eval(xy);"
102 , fChildSize(child_size) {}
110 if (!fContentShader || this->hasChildrenInval()) {
111 const auto& child = this->children()[0];
122 return fContentShader;
131 float adjHeight =
std::abs(fHeight)/4;
132 float r = (1 + adjHeight)/2/
sqrt(adjHeight);
133 float h = std::pow(adjHeight, 3)*1.3;
134 builder.uniform(
"u_center") = fCenter;
135 builder.uniform(
"u_radius") = fRadius;
138 builder.uniform(
"u_rcpR") = 1.0f/r;
139 builder.uniform(
"u_rcpAsinInvR") = 1.0f/std::asin(1/r);
140 builder.uniform(
"u_selector") = (fHeight > 0 ? 1.0f : -1.0f);
142 builder.child(
"u_layer") = this->contentShader();
148 const auto& child = this->children()[0];
149 fEffectShader = buildEffectShader();
150 return child->revalidate(ic, ctm);
153 void onRender(
SkCanvas* canvas,
const RenderContext* ctx)
const override {
155 this->children()[0]->render(canvas, ctx);
159 const auto local_ctx = ScopedRenderContext(canvas, ctx)
171 const RenderNode* onNodeAt(
const SkPoint&)
const override {
return nullptr; }
184class BulgeEffectAdapter final :
public DiscardableAdapterBase<BulgeEffectAdapter,
188 const AnimationBuilder& abuilder,
193 kHorizontalRadius_Index = 0,
194 kVerticalRadius_Index = 1,
195 kBulgeCenter_Index = 2,
196 kBulgeHeight_Index = 3,
201 EffectBinder(jprops, abuilder,
this).bind(kHorizontalRadius_Index, fHorizontalRadius)
202 .bind(kVerticalRadius_Index, fVerticalRadius)
203 .bind(kBulgeCenter_Index, fCenter)
204 .bind(kBulgeHeight_Index, fBulgeHeight);
208 void onSync()
override {
210 auto n = this->node();
211 n->setCenter({fCenter.
x, fCenter.
y});
212 n->setRadius({fHorizontalRadius, fVerticalRadius});
213 n->setHeight(fBulgeHeight);
220 using INHERITED = DiscardableAdapterBase<BulgeEffectAdapter, BulgeNode>;
227 auto shaderNode = sk_make_sp<BulgeNode>(std::move(layer), fLayerSize);
229 std::move(shaderNode));
@ kSrcOver
r = s + (1-sa)*d
#define INHERITED(method,...)
sk_sp< T > sk_ref_sp(T *obj)
#define SG_ATTRIBUTE(attr_name, attr_type, attr_container)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
void drawPaint(const SkPaint &paint)
SkMatrix getTotalMatrix() const
static const SkMatrix & I()
void setShader(sk_sp< SkShader > shader)
void setBlendMode(SkBlendMode mode)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode, const SkMatrix *localMatrix, const SkRect *tileRect) const
static Result MakeForShader(SkString sksl, const Options &)
void attachDiscardableAdapter(sk_sp< T > adapter) const
Optional< SkRect > bounds
SIN Vec< N, float > abs(const Vec< N, float > &x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
constexpr float y() const
constexpr float x() const
static constexpr SkRect MakeSize(const SkSize &size)