Merge "Remove NewWeakGlobalRef from RenderNode"

This commit is contained in:
John Reck
2021-08-03 22:29:33 +00:00
committed by Android (Google) Code Review
2 changed files with 97 additions and 55 deletions

View File

@@ -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

View File

@@ -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));
}