xref: /aosp_15_r20/external/skia/modules/jetski/src/Gradients.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2021 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include <jni.h>
9 
10 #include "include/core/SkColorSpace.h"
11 #include "include/core/SkM44.h"
12 #include "include/effects/SkGradientShader.h"
13 #include "modules/jetski/src/Utils.h"
14 
15 namespace {
16 
17 // Helper for common gradient data access.
18 class GradientData {
19 public:
GradientData(JNIEnv * env,const jfloatArray & jcolors,const jfloatArray & jpos,jint jtm,jlong native_lm)20     GradientData(JNIEnv* env, const jfloatArray& jcolors, const jfloatArray& jpos,
21                  jint jtm, jlong native_lm)
22         : fEnv(env)
23         , fJColors(jcolors)
24         , fJPos(jpos)
25         , fColors(env->GetFloatArrayElements(jcolors, nullptr))
26         , fPos(env->GetFloatArrayElements(jpos, nullptr))
27         , fCount(env->GetArrayLength(jpos))
28         , fTileMode(jetski::utils::TileMode(jtm))
29         , fLocalMatrix(native_lm ? reinterpret_cast<const SkM44*>(native_lm)->asM33() : SkMatrix())
30     {
31         SkASSERT(env->GetArrayLength(jcolors) == 4*fCount);
32     }
33 
~GradientData()34     ~GradientData() {
35         fEnv->ReleaseFloatArrayElements(fJPos, fPos, 0);
36         fEnv->ReleaseFloatArrayElements(fJColors, fColors, 0);
37     }
38 
count() const39     int count() const { return fCount; }
40 
colors() const41     const SkColor4f*  colors()      const { return reinterpret_cast<const SkColor4f*>(fColors); }
pos() const42     const float*      pos()         const { return fPos; }
tileMode() const43     const SkTileMode& tileMode()    const { return fTileMode; }
localMatrix() const44     const SkMatrix&   localMatrix() const { return fLocalMatrix; }
45 
46 private:
47     JNIEnv*            fEnv;
48     const jfloatArray& fJColors;
49     const jfloatArray& fJPos;
50     float*             fColors;
51     float*             fPos;
52     const int          fCount;
53     const SkTileMode   fTileMode;
54     const SkMatrix     fLocalMatrix;
55 };
56 
MakeLinear(JNIEnv * env,jobject,jfloat x0,jfloat y0,jfloat x1,jfloat y1,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)57 static jlong MakeLinear(JNIEnv* env, jobject, jfloat x0, jfloat y0, jfloat x1, jfloat y1,
58                         jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
59     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
60     const SkPoint pts[] = {{x0, y0}, {x1, y1}};
61 
62     auto shader = SkGradientShader::MakeLinear(pts,
63                                                gdata.colors(),
64                                                nullptr,
65                                                gdata.pos(),
66                                                gdata.count(),
67                                                gdata.tileMode(),
68                                                0,
69                                                &gdata.localMatrix());
70 
71     return reinterpret_cast<jlong>(shader.release());
72 }
73 
MakeRadial(JNIEnv * env,jobject,jfloat x,jfloat y,jfloat r,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)74 static jlong MakeRadial(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat r,
75                         jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
76     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
77 
78     auto shader = SkGradientShader::MakeRadial({x,y}, r,
79                                                gdata.colors(),
80                                                nullptr,
81                                                gdata.pos(),
82                                                gdata.count(),
83                                                gdata.tileMode(),
84                                                0,
85                                                &gdata.localMatrix());
86 
87     return reinterpret_cast<jlong>(shader.release());
88 }
89 
MakeTwoPointConical(JNIEnv * env,jobject,jfloat x0,jfloat y0,jfloat r0,jfloat x1,jfloat y1,jfloat r1,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)90 static jlong MakeTwoPointConical(JNIEnv* env, jobject,
91                                  jfloat x0, jfloat y0, jfloat r0,
92                                  jfloat x1, jfloat y1, jfloat r1,
93                                  jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
94     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
95 
96     auto shader = SkGradientShader::MakeTwoPointConical({x0,y0}, r0,
97                                                         {x1,y1}, r1,
98                                                         gdata.colors(),
99                                                         nullptr,
100                                                         gdata.pos(),
101                                                         gdata.count(),
102                                                         gdata.tileMode(),
103                                                         0,
104                                                         &gdata.localMatrix());
105 
106     return reinterpret_cast<jlong>(shader.release());
107 }
108 
MakeSweep(JNIEnv * env,jobject,jfloat x,jfloat y,jfloat sa,jfloat ea,jfloatArray jcolors,jfloatArray jpos,jint jtm,jlong native_lm)109 static jlong MakeSweep(JNIEnv* env, jobject, jfloat x, jfloat y, jfloat sa, jfloat ea,
110                        jfloatArray jcolors, jfloatArray jpos, jint jtm, jlong native_lm) {
111     const GradientData gdata(env, jcolors, jpos, jtm, native_lm);
112 
113     auto shader = SkGradientShader::MakeSweep(x, y,
114                                               gdata.colors(),
115                                               nullptr,
116                                               gdata.pos(),
117                                               gdata.count(),
118                                               gdata.tileMode(),
119                                               sa, ea,
120                                               0,
121                                               &gdata.localMatrix());
122 
123     return reinterpret_cast<jlong>(shader.release());
124 }
125 
126 } // namespace
127 
register_jetski_LinearGradient(JNIEnv * env)128 int register_jetski_LinearGradient(JNIEnv* env) {
129     static const JNINativeMethod methods[] = {
130         {"nMakeLinear", "(FFFF[F[FIJ)J", reinterpret_cast<void*>(MakeLinear)},
131     };
132 
133     const auto clazz = env->FindClass("org/skia/jetski/LinearGradient");
134     return clazz
135         ? env->RegisterNatives(clazz, methods, std::size(methods))
136         : JNI_ERR;
137 }
138 
register_jetski_RadialGradient(JNIEnv * env)139 int register_jetski_RadialGradient(JNIEnv* env) {
140     static const JNINativeMethod methods[] = {
141         {"nMakeRadial", "(FFF[F[FIJ)J", reinterpret_cast<void*>(MakeRadial)},
142     };
143 
144     const auto clazz = env->FindClass("org/skia/jetski/RadialGradient");
145     return clazz
146         ? env->RegisterNatives(clazz, methods, std::size(methods))
147         : JNI_ERR;
148 }
149 
register_jetski_TwoPointConicalGradient(JNIEnv * env)150 int register_jetski_TwoPointConicalGradient(JNIEnv* env) {
151     static const JNINativeMethod methods[] = {
152         {"nMakeTwoPointConical", "(FFFFFF[F[FIJ)J", reinterpret_cast<void*>(MakeTwoPointConical)},
153     };
154 
155     const auto clazz = env->FindClass("org/skia/jetski/TwoPointConicalGradient");
156     return clazz
157         ? env->RegisterNatives(clazz, methods, std::size(methods))
158         : JNI_ERR;
159 }
160 
register_jetski_SweepGradient(JNIEnv * env)161 int register_jetski_SweepGradient(JNIEnv* env) {
162     static const JNINativeMethod methods[] = {
163         {"nMakeSweep", "(FFFF[F[FIJ)J", reinterpret_cast<void*>(MakeSweep)},
164     };
165 
166     const auto clazz = env->FindClass("org/skia/jetski/SweepGradient");
167     return clazz
168         ? env->RegisterNatives(clazz, methods, std::size(methods))
169         : JNI_ERR;
170 }
171