summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Eric Miao <ericymiao@google.com> 2024-07-10 17:11:10 -0700
committer Eric Miao <ericymiao@google.com> 2024-07-24 09:49:17 -0700
commit6e5ce89b93f46a94febfe1433f167181b1174586 (patch)
tree49f49da3f40caae475cb2f631e5acc7db25fb33c
parente0b7812fa517db725a3e0ca31365a9d94ef521d7 (diff)
Initialize some global variables in Bitmap.cpp when needed
Bug: 331243037 Flag: EXEMPT bugfix This allows Bitmap class to have a static NativeAllocationRegistry, which can be used to register native allocations of different sizes without creating multiple registries. To make this possible, the static native method nativeGetNativeFinalizer needs to be available during static initialization time in Bitmap class. However, there is a deadlock as shown below which needs to be removed e.g. class Bitmap { private static long sFinalizer = nativeGetNativeFinalizer(); private static native long nativeGetNativeFinalizer(); } The static initialization of sFinalizer depends on the native JNI call nativeGetNativeFinalizer() to be available/registered. However, during JNI registration time in Bitmap.cpp, the calls of GetMethodID() requires the static initialization to be done, this causes deadlock, and hence the code above wouldn't work. To remove this deadlock and thus allow static native methods to be called during static initialization, we moved the initialization of these global variables in Bitmap.cpp, which depends on GetMethodID(), to be done later when they are needed first time. Change-Id: I87bebdbe128a2dad48b162d31ed275ad7908bcd7
-rw-r--r--libs/hwui/jni/Bitmap.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index d4157008ca46..010c4e8dfb3a 100644
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -33,9 +33,6 @@
#define DEBUG_PARCEL 0
static jclass gBitmap_class;
-static jfieldID gBitmap_nativePtr;
-static jmethodID gBitmap_constructorMethodID;
-static jmethodID gBitmap_reinitMethodID;
namespace android {
@@ -183,6 +180,9 @@ static void assert_premultiplied(const SkImageInfo& info, bool isPremultiplied)
void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
bool isPremultiplied)
{
+ static jmethodID gBitmap_reinitMethodID =
+ GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V");
+
// The caller needs to have already set the alpha type properly, so the
// native SkBitmap stays in sync with the Java Bitmap.
assert_premultiplied(info, isPremultiplied);
@@ -194,6 +194,10 @@ void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets,
int density) {
+ static jmethodID gBitmap_constructorMethodID =
+ GetMethodIDOrDie(env, gBitmap_class,
+ "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
+
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
// The caller needs to have already set the alpha type properly, so the
@@ -232,11 +236,17 @@ Bitmap& toBitmap(jlong bitmapHandle) {
using namespace android;
using namespace android::bitmap;
+static inline jlong getNativePtr(JNIEnv* env, jobject bitmap) {
+ static jfieldID gBitmap_nativePtr =
+ GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J");
+ return env->GetLongField(bitmap, gBitmap_nativePtr);
+}
+
Bitmap* GraphicsJNI::getNativeBitmap(JNIEnv* env, jobject bitmap) {
SkASSERT(env);
SkASSERT(bitmap);
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
- jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
+ jlong bitmapHandle = getNativePtr(env, bitmap);
LocalScopedBitmap localBitmap(bitmapHandle);
return localBitmap.valid() ? &localBitmap->bitmap() : nullptr;
}
@@ -246,7 +256,7 @@ SkImageInfo GraphicsJNI::getBitmapInfo(JNIEnv* env, jobject bitmap, uint32_t* ou
SkASSERT(env);
SkASSERT(bitmap);
SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
- jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
+ jlong bitmapHandle = getNativePtr(env, bitmap);
LocalScopedBitmap localBitmap(bitmapHandle);
if (outRowBytes) {
*outRowBytes = localBitmap->rowBytes();
@@ -1269,9 +1279,6 @@ static const JNINativeMethod gBitmapMethods[] = {
int register_android_graphics_Bitmap(JNIEnv* env)
{
gBitmap_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Bitmap"));
- gBitmap_nativePtr = GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J");
- gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
- gBitmap_reinitMethodID = GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V");
uirenderer::HardwareBufferHelpers::init();
return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods,
NELEM(gBitmapMethods));