Remove NewWeakGlobalRef from RenderNode
Bug: 194893628 Test: make && CtsUiRenderingTestCases Change-Id: I90d9d96ed940812c9dca1385f4a71d0a0cd2936f
This commit is contained in:
@@ -35,6 +35,7 @@ import libcore.util.NativeAllocationRegistry;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
|
||||
@@ -263,7 +264,6 @@ public final class RenderNode {
|
||||
* @hide
|
||||
*/
|
||||
public interface PositionUpdateListener {
|
||||
|
||||
/**
|
||||
* Called by native by a Rendering Worker thread to update window position
|
||||
*
|
||||
@@ -271,6 +271,21 @@ public final class RenderNode {
|
||||
*/
|
||||
void positionChanged(long frameNumber, int left, int top, int right, int bottom);
|
||||
|
||||
/**
|
||||
* Called by JNI
|
||||
*
|
||||
* @hide */
|
||||
static boolean callPositionChanged(WeakReference<PositionUpdateListener> weakListener,
|
||||
long frameNumber, int left, int top, int right, int bottom) {
|
||||
final PositionUpdateListener listener = weakListener.get();
|
||||
if (listener != null) {
|
||||
listener.positionChanged(frameNumber, left, top, right, bottom);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to apply a stretch effect to any child SurfaceControl layers
|
||||
*
|
||||
@@ -285,6 +300,26 @@ public final class RenderNode {
|
||||
float maxStretchX, float maxStretchY, float childRelativeLeft,
|
||||
float childRelativeTop, float childRelativeRight, float childRelativeBottom) { }
|
||||
|
||||
/**
|
||||
* Called by JNI
|
||||
*
|
||||
* @hide */
|
||||
static boolean callApplyStretch(WeakReference<PositionUpdateListener> weakListener,
|
||||
long frameNumber, float width, float height,
|
||||
float vecX, float vecY,
|
||||
float maxStretchX, float maxStretchY, float childRelativeLeft,
|
||||
float childRelativeTop, float childRelativeRight, float childRelativeBottom) {
|
||||
final PositionUpdateListener listener = weakListener.get();
|
||||
if (listener != null) {
|
||||
listener.applyStretch(frameNumber, width, height, vecX, vecY, maxStretchX,
|
||||
maxStretchY, childRelativeLeft, childRelativeTop, childRelativeRight,
|
||||
childRelativeBottom);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by native on RenderThread to notify that the view is no longer in the
|
||||
* draw tree. UI thread is blocked at this point.
|
||||
@@ -293,6 +328,21 @@ public final class RenderNode {
|
||||
*/
|
||||
void positionLost(long frameNumber);
|
||||
|
||||
/**
|
||||
* Called by JNI
|
||||
*
|
||||
* @hide */
|
||||
static boolean callPositionLost(WeakReference<PositionUpdateListener> weakListener,
|
||||
long frameNumber) {
|
||||
final PositionUpdateListener listener = weakListener.get();
|
||||
if (listener != null) {
|
||||
listener.positionLost(frameNumber);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class CompositePositionUpdateListener implements PositionUpdateListener {
|
||||
@@ -353,7 +403,7 @@ public final class RenderNode {
|
||||
comp = comp.with(listener);
|
||||
}
|
||||
mCompositePositionUpdateListener = comp;
|
||||
nRequestPositionUpdates(mNativeRenderNode, comp);
|
||||
nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,7 +418,7 @@ public final class RenderNode {
|
||||
if (comp != null) {
|
||||
comp = comp.without(listener);
|
||||
mCompositePositionUpdateListener = comp;
|
||||
nRequestPositionUpdates(mNativeRenderNode, comp);
|
||||
nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1575,7 +1625,7 @@ public final class RenderNode {
|
||||
private static native int nGetAllocatedSize(long renderNode);
|
||||
|
||||
private static native void nRequestPositionUpdates(long renderNode,
|
||||
PositionUpdateListener callback);
|
||||
WeakReference<PositionUpdateListener> callback);
|
||||
|
||||
// Animations
|
||||
|
||||
|
||||
@@ -547,9 +547,12 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
|
||||
// SurfaceView position callback
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
jmethodID gPositionListener_PositionChangedMethod;
|
||||
jmethodID gPositionListener_ApplyStretchMethod;
|
||||
jmethodID gPositionListener_PositionLostMethod;
|
||||
struct {
|
||||
jclass clazz;
|
||||
jmethodID callPositionChanged;
|
||||
jmethodID callApplyStretch;
|
||||
jmethodID callPositionLost;
|
||||
} gPositionListener;
|
||||
|
||||
static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
jlong renderNodePtr, jobject listener) {
|
||||
@@ -557,16 +560,16 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
public:
|
||||
PositionListenerTrampoline(JNIEnv* env, jobject listener) {
|
||||
env->GetJavaVM(&mVm);
|
||||
mWeakRef = env->NewWeakGlobalRef(listener);
|
||||
mListener = env->NewGlobalRef(listener);
|
||||
}
|
||||
|
||||
virtual ~PositionListenerTrampoline() {
|
||||
jnienv()->DeleteWeakGlobalRef(mWeakRef);
|
||||
mWeakRef = nullptr;
|
||||
jnienv()->DeleteGlobalRef(mListener);
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override {
|
||||
if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return;
|
||||
if (CC_UNLIKELY(!mListener || !info.updateWindowPositions)) return;
|
||||
|
||||
Matrix4 transform;
|
||||
info.damageAccumulator->computeCurrentTransform(&transform);
|
||||
@@ -609,7 +612,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
}
|
||||
|
||||
virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override {
|
||||
if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return;
|
||||
if (CC_UNLIKELY(!mListener || (info && !info->updateWindowPositions))) return;
|
||||
|
||||
if (mPreviousPosition.isEmpty()) {
|
||||
return;
|
||||
@@ -618,18 +621,16 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
|
||||
ATRACE_NAME("SurfaceView position lost");
|
||||
JNIEnv* env = jnienv();
|
||||
jobject localref = env->NewLocalRef(mWeakRef);
|
||||
if (CC_UNLIKELY(!localref)) {
|
||||
env->DeleteWeakGlobalRef(mWeakRef);
|
||||
mWeakRef = nullptr;
|
||||
return;
|
||||
}
|
||||
#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
|
||||
// TODO: Remember why this is synchronous and then make a comment
|
||||
env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
|
||||
jboolean keepListening = env->CallStaticBooleanMethod(
|
||||
gPositionListener.clazz, gPositionListener.callPositionLost, mListener,
|
||||
info ? info->canvasContext.getFrameNumber() : 0);
|
||||
if (!keepListening) {
|
||||
env->DeleteGlobalRef(mListener);
|
||||
mListener = nullptr;
|
||||
}
|
||||
#endif
|
||||
env->DeleteLocalRef(localref);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -684,28 +685,20 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
StretchEffectBehavior::Shader) {
|
||||
JNIEnv* env = jnienv();
|
||||
|
||||
jobject localref = env->NewLocalRef(mWeakRef);
|
||||
if (CC_UNLIKELY(!localref)) {
|
||||
env->DeleteWeakGlobalRef(mWeakRef);
|
||||
mWeakRef = nullptr;
|
||||
return;
|
||||
}
|
||||
#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
|
||||
SkVector stretchDirection = effect->getStretchDirection();
|
||||
env->CallVoidMethod(localref, gPositionListener_ApplyStretchMethod,
|
||||
info.canvasContext.getFrameNumber(),
|
||||
result.width,
|
||||
result.height,
|
||||
stretchDirection.fX,
|
||||
stretchDirection.fY,
|
||||
effect->maxStretchAmountX,
|
||||
effect->maxStretchAmountY,
|
||||
childRelativeBounds.left(),
|
||||
childRelativeBounds.top(),
|
||||
childRelativeBounds.right(),
|
||||
childRelativeBounds.bottom());
|
||||
jboolean keepListening = env->CallStaticBooleanMethod(
|
||||
gPositionListener.clazz, gPositionListener.callApplyStretch, mListener,
|
||||
info.canvasContext.getFrameNumber(), result.width, result.height,
|
||||
stretchDirection.fX, stretchDirection.fY, effect->maxStretchAmountX,
|
||||
effect->maxStretchAmountY, childRelativeBounds.left(),
|
||||
childRelativeBounds.top(), childRelativeBounds.right(),
|
||||
childRelativeBounds.bottom());
|
||||
if (!keepListening) {
|
||||
env->DeleteGlobalRef(mListener);
|
||||
mListener = nullptr;
|
||||
}
|
||||
#endif
|
||||
env->DeleteLocalRef(localref);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,14 +707,12 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
ATRACE_NAME("Update SurfaceView position");
|
||||
|
||||
JNIEnv* env = jnienv();
|
||||
jobject localref = env->NewLocalRef(mWeakRef);
|
||||
if (CC_UNLIKELY(!localref)) {
|
||||
env->DeleteWeakGlobalRef(mWeakRef);
|
||||
mWeakRef = nullptr;
|
||||
} else {
|
||||
env->CallVoidMethod(localref, gPositionListener_PositionChangedMethod,
|
||||
frameNumber, left, top, right, bottom);
|
||||
env->DeleteLocalRef(localref);
|
||||
jboolean keepListening = env->CallStaticBooleanMethod(
|
||||
gPositionListener.clazz, gPositionListener.callPositionChanged, mListener,
|
||||
frameNumber, left, top, right, bottom);
|
||||
if (!keepListening) {
|
||||
env->DeleteGlobalRef(mListener);
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
// We need to release ourselves here
|
||||
@@ -729,7 +720,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
||||
}
|
||||
|
||||
JavaVM* mVm;
|
||||
jobject mWeakRef;
|
||||
jobject mListener;
|
||||
uirenderer::Rect mPreviousPosition;
|
||||
};
|
||||
|
||||
@@ -754,7 +745,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"nGetAllocatedSize", "(J)I", (void*)android_view_RenderNode_getAllocatedSize},
|
||||
{"nAddAnimator", "(JJ)V", (void*)android_view_RenderNode_addAnimator},
|
||||
{"nEndAllAnimators", "(J)V", (void*)android_view_RenderNode_endAllAnimators},
|
||||
{"nRequestPositionUpdates", "(JLandroid/graphics/RenderNode$PositionUpdateListener;)V",
|
||||
{"nRequestPositionUpdates", "(JLjava/lang/ref/WeakReference;)V",
|
||||
(void*)android_view_RenderNode_requestPositionUpdates},
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -852,12 +843,13 @@ static const JNINativeMethod gMethods[] = {
|
||||
|
||||
int register_android_view_RenderNode(JNIEnv* env) {
|
||||
jclass clazz = FindClassOrDie(env, "android/graphics/RenderNode$PositionUpdateListener");
|
||||
gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
|
||||
"positionChanged", "(JIIII)V");
|
||||
gPositionListener_ApplyStretchMethod =
|
||||
GetMethodIDOrDie(env, clazz, "applyStretch", "(JFFFFFFFFFF)V");
|
||||
gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
|
||||
"positionLost", "(J)V");
|
||||
gPositionListener.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
gPositionListener.callPositionChanged = GetStaticMethodIDOrDie(
|
||||
env, clazz, "callPositionChanged", "(Ljava/lang/ref/WeakReference;JIIII)Z");
|
||||
gPositionListener.callApplyStretch = GetStaticMethodIDOrDie(
|
||||
env, clazz, "callApplyStretch", "(Ljava/lang/ref/WeakReference;JFFFFFFFFFF)Z");
|
||||
gPositionListener.callPositionLost = GetStaticMethodIDOrDie(
|
||||
env, clazz, "callPositionLost", "(Ljava/lang/ref/WeakReference;J)Z");
|
||||
return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user