xref: /aosp_15_r20/frameworks/base/libs/hwui/jni/MaskFilter.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 #include "GraphicsJNI.h"
2 #include "SkMaskFilter.h"
3 #include "SkBlurMaskFilter.h"
4 #include "SkBlurTypes.h"
5 #include "SkTableMaskFilter.h"
6 
ThrowIAE_IfNull(JNIEnv * env,void * ptr)7 static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
8     if (NULL == ptr) {
9         doThrowIAE(env);
10     }
11 }
12 
13 // From https://skia.googlesource.com/skia/+/d74c99a3cd5eef5f16b2eb226e6b45fe523c8552/src/core/SkBlurMask.cpp#28
14 static constexpr float kBLUR_SIGMA_SCALE = 0.57735f;
15 
convertRadiusToSigma(float radius)16 static float convertRadiusToSigma(float radius) {
17     return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f;
18 }
19 
20 class SkMaskFilterGlue {
21 public:
destructor(JNIEnv * env,jobject,jlong filterHandle)22     static void destructor(JNIEnv* env, jobject, jlong filterHandle) {
23         SkMaskFilter* filter = reinterpret_cast<SkMaskFilter *>(filterHandle);
24         SkSafeUnref(filter);
25     }
26 
createBlur(JNIEnv * env,jobject,jfloat radius,jint blurStyle)27     static jlong createBlur(JNIEnv* env, jobject, jfloat radius, jint blurStyle) {
28         SkScalar sigma = convertRadiusToSigma(radius);
29         SkMaskFilter* filter = SkMaskFilter::MakeBlur((SkBlurStyle)blurStyle, sigma).release();
30         ThrowIAE_IfNull(env, filter);
31         return reinterpret_cast<jlong>(filter);
32     }
33 
createEmboss(JNIEnv * env,jobject,jfloatArray dirArray,jfloat ambient,jfloat specular,jfloat radius)34     static jlong createEmboss(JNIEnv* env, jobject, jfloatArray dirArray, jfloat ambient, jfloat specular, jfloat radius) {
35         SkScalar direction[3];
36 
37         AutoJavaFloatArray autoDir(env, dirArray, 3);
38         float* values = autoDir.ptr();
39         for (int i = 0; i < 3; i++) {
40             direction[i] = values[i];
41         }
42 
43         SkScalar sigma = convertRadiusToSigma(radius);
44         SkMaskFilter* filter =  SkBlurMaskFilter::MakeEmboss(sigma,
45                 direction, ambient, specular).release();
46         ThrowIAE_IfNull(env, filter);
47         return reinterpret_cast<jlong>(filter);
48     }
49 
createTable(JNIEnv * env,jobject,jbyteArray jtable)50     static jlong createTable(JNIEnv* env, jobject, jbyteArray jtable) {
51         AutoJavaByteArray autoTable(env, jtable, 256);
52         SkMaskFilter* filter = SkTableMaskFilter::Create((const uint8_t*)autoTable.ptr());
53         return reinterpret_cast<jlong>(filter);
54     }
55 
createClipTable(JNIEnv * env,jobject,jint min,jint max)56     static jlong createClipTable(JNIEnv* env, jobject, jint min, jint max) {
57         SkMaskFilter* filter = SkTableMaskFilter::CreateClip(min, max);
58         return reinterpret_cast<jlong>(filter);
59     }
60 
createGammaTable(JNIEnv * env,jobject,jfloat gamma)61     static jlong createGammaTable(JNIEnv* env, jobject, jfloat gamma) {
62         SkMaskFilter* filter = SkTableMaskFilter::CreateGamma(gamma);
63         return reinterpret_cast<jlong>(filter);
64     }
65 };
66 
67 static const JNINativeMethod gMaskFilterMethods[] = {
68     { "nativeDestructor",   "(J)V",     (void*)SkMaskFilterGlue::destructor      }
69 };
70 
71 static const JNINativeMethod gBlurMaskFilterMethods[] = {
72     { "nativeConstructor",  "(FI)J",    (void*)SkMaskFilterGlue::createBlur      }
73 };
74 
75 static const JNINativeMethod gEmbossMaskFilterMethods[] = {
76     { "nativeConstructor",  "([FFFF)J", (void*)SkMaskFilterGlue::createEmboss    }
77 };
78 
79 static const JNINativeMethod gTableMaskFilterMethods[] = {
80     { "nativeNewTable", "([B)J", (void*)SkMaskFilterGlue::createTable    },
81     { "nativeNewClip",  "(II)J", (void*)SkMaskFilterGlue::createClipTable    },
82     { "nativeNewGamma", "(F)J", (void*)SkMaskFilterGlue::createGammaTable    }
83 };
84 
register_android_graphics_MaskFilter(JNIEnv * env)85 int register_android_graphics_MaskFilter(JNIEnv* env)
86 {
87     android::RegisterMethodsOrDie(env, "android/graphics/MaskFilter", gMaskFilterMethods,
88                                   NELEM(gMaskFilterMethods));
89     android::RegisterMethodsOrDie(env, "android/graphics/BlurMaskFilter", gBlurMaskFilterMethods,
90                                   NELEM(gBlurMaskFilterMethods));
91     android::RegisterMethodsOrDie(env, "android/graphics/EmbossMaskFilter",
92                                   gEmbossMaskFilterMethods, NELEM(gEmbossMaskFilterMethods));
93     android::RegisterMethodsOrDie(env, "android/graphics/TableMaskFilter", gTableMaskFilterMethods,
94                                   NELEM(gTableMaskFilterMethods));
95 
96     return 0;
97 }
98