Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38491dfa authored by Rob Carr's avatar Rob Carr Committed by Automerger Merge Worker
Browse files

Merge "ViewRootImpl/SurfaceView: Listen for queue stalls" into tm-dev am: 7a0ee72b

parents 3445e4ee 7a0ee72b
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -1208,8 +1208,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        }
        }
        mTransformHint = viewRoot.getBufferTransformHint();
        mTransformHint = viewRoot.getBufferTransformHint();
        mBlastSurfaceControl.setTransformHint(mTransformHint);
        mBlastSurfaceControl.setTransformHint(mTransformHint);

        mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
        mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
        mBlastBufferQueue.setTransactionHangCallback(ViewRootImpl.sTransactionHangCallback);
    }
    }


    private void onDrawFinished() {
    private void onDrawFinished() {
+23 −0
Original line number Original line Diff line number Diff line
@@ -858,6 +858,28 @@ public final class ViewRootImpl implements ViewParent,
     */
     */
    private Bundle mRelayoutBundle = new Bundle();
    private Bundle mRelayoutBundle = new Bundle();


    private static volatile boolean sAnrReported = false;
    static BLASTBufferQueue.TransactionHangCallback sTransactionHangCallback =
        new BLASTBufferQueue.TransactionHangCallback() {
            @Override
            public void onTransactionHang(boolean isGPUHang) {
                if (isGPUHang && !sAnrReported) {
                    sAnrReported = true;
                    try {
                        ActivityManager.getService().appNotResponding(
                            "Buffer processing hung up due to stuck fence. Indicates GPU hang");
                    } catch (RemoteException e) {
                        // We asked the system to crash us, but the system
                        // already crashed. Unfortunately things may be
                        // out of control.
                    }
                } else {
                    // TODO: Do something with this later. For now we just ANR
                    // in dequeue buffer later like we always have.
                }
            }
        };

    private String mTag = TAG;
    private String mTag = TAG;


    public ViewRootImpl(Context context, Display display) {
    public ViewRootImpl(Context context, Display display) {
@@ -2100,6 +2122,7 @@ public final class ViewRootImpl implements ViewParent,
        }
        }
        mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
        mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format);
                mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format);
        mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);
        Surface blastSurface = mBlastBufferQueue.createSurface();
        Surface blastSurface = mBlastBufferQueue.createSurface();
        // Only call transferFrom if the surface has changed to prevent inc the generation ID and
        // Only call transferFrom if the surface has changed to prevent inc the generation ID and
        // causing EGL resources to be recreated.
        // causing EGL resources to be recreated.
+60 −1
Original line number Original line Diff line number Diff line
@@ -47,6 +47,43 @@ static JNIEnv* getenv(JavaVM* vm) {
    return env;
    return env;
}
}


  struct {
    jmethodID onTransactionHang;
} gTransactionHangCallback;

class TransactionHangCallbackWrapper : public LightRefBase<TransactionHangCallbackWrapper> {
public:
    explicit TransactionHangCallbackWrapper(JNIEnv* env, jobject jobject) {
        env->GetJavaVM(&mVm);
        mTransactionHangObject = env->NewGlobalRef(jobject);
        LOG_ALWAYS_FATAL_IF(!mTransactionHangObject, "Failed to make global ref");
    }

    ~TransactionHangCallbackWrapper() {
        if (mTransactionHangObject) {
            getenv()->DeleteGlobalRef(mTransactionHangObject);
            mTransactionHangObject = nullptr;
        }
    }

    void onTransactionHang(bool isGpuHang) {
        if (mTransactionHangObject) {
            getenv()->CallVoidMethod(mTransactionHangObject,
                                     gTransactionHangCallback.onTransactionHang, isGpuHang);
        }
    }

private:
    JavaVM* mVm;
    jobject mTransactionHangObject;

    JNIEnv* getenv() {
        JNIEnv* env;
        mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
        return env;
    }
};

static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
                          jboolean updateDestinationFrame) {
                          jboolean updateDestinationFrame) {
    ScopedUtfChars name(env, jName);
    ScopedUtfChars name(env, jName);
@@ -142,6 +179,20 @@ static bool nativeIsSameSurfaceControl(JNIEnv* env, jclass clazz, jlong ptr, jlo
    return queue->isSameSurfaceControl(reinterpret_cast<SurfaceControl*>(surfaceControl));
    return queue->isSameSurfaceControl(reinterpret_cast<SurfaceControl*>(surfaceControl));
}
}
  
  
static void nativeSetTransactionHangCallback(JNIEnv* env, jclass clazz, jlong ptr,
                                             jobject transactionHangCallback) {
    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
    if (transactionHangCallback == nullptr) {
        queue->setTransactionHangCallback(nullptr);
    } else {
        sp<TransactionHangCallbackWrapper> wrapper =
                new TransactionHangCallbackWrapper{env, transactionHangCallback};
        queue->setTransactionHangCallback([wrapper](bool isGpuHang) {
            wrapper->onTransactionHang(isGpuHang);
        });
    }
}

static jobject nativeGatherPendingTransactions(JNIEnv* env, jclass clazz, jlong ptr,
static jobject nativeGatherPendingTransactions(JNIEnv* env, jclass clazz, jlong ptr,
                                               jlong frameNum) {
                                               jlong frameNum) {
    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
@@ -163,7 +214,10 @@ static const JNINativeMethod gMethods[] = {
        {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
        {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
        {"nativeApplyPendingTransactions", "(JJ)V", (void*)nativeApplyPendingTransactions},
        {"nativeApplyPendingTransactions", "(JJ)V", (void*)nativeApplyPendingTransactions},
        {"nativeIsSameSurfaceControl", "(JJ)Z", (void*)nativeIsSameSurfaceControl},
        {"nativeIsSameSurfaceControl", "(JJ)Z", (void*)nativeIsSameSurfaceControl},
        {"nativeGatherPendingTransactions", "(JJ)Landroid/view/SurfaceControl$Transaction;", (void*)nativeGatherPendingTransactions}
        {"nativeGatherPendingTransactions", "(JJ)Landroid/view/SurfaceControl$Transaction;", (void*)nativeGatherPendingTransactions},
        {"nativeSetTransactionHangCallback",
         "(JLandroid/graphics/BLASTBufferQueue$TransactionHangCallback;)V",
         (void*)nativeSetTransactionHangCallback},
        // clang-format on
        // clang-format on
};
};


@@ -180,6 +234,11 @@ int register_android_graphics_BLASTBufferQueue(JNIEnv* env) {
    jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
    jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
    gTransactionConsumer.accept =
    gTransactionConsumer.accept =
            GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
            GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
    jclass transactionHangClass =
            FindClassOrDie(env, "android/graphics/BLASTBufferQueue$TransactionHangCallback");
    gTransactionHangCallback.onTransactionHang =
            GetMethodIDOrDie(env, transactionHangClass, "onTransactionHang", "(Z)V");

    return 0;
    return 0;
}
}


+10 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,12 @@ public final class BLASTBufferQueue {
    private static native boolean nativeIsSameSurfaceControl(long ptr, long surfaceControlPtr);
    private static native boolean nativeIsSameSurfaceControl(long ptr, long surfaceControlPtr);
    private static native SurfaceControl.Transaction nativeGatherPendingTransactions(long ptr,
    private static native SurfaceControl.Transaction nativeGatherPendingTransactions(long ptr,
            long frameNumber);
            long frameNumber);
    private static native void nativeSetTransactionHangCallback(long ptr,
            TransactionHangCallback callback);

    public interface TransactionHangCallback {
        void onTransactionHang(boolean isGpuHang);
    }


    /** Create a new connection with the surface flinger. */
    /** Create a new connection with the surface flinger. */
    public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
    public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
@@ -184,4 +190,8 @@ public final class BLASTBufferQueue {
    public SurfaceControl.Transaction gatherPendingTransactions(long frameNumber) {
    public SurfaceControl.Transaction gatherPendingTransactions(long frameNumber) {
        return nativeGatherPendingTransactions(mNativeObject, frameNumber);
        return nativeGatherPendingTransactions(mNativeObject, frameNumber);
    }
    }

    public void setTransactionHangCallback(TransactionHangCallback hangCallback) {
        nativeSetTransactionHangCallback(mNativeObject, hangCallback);
    }
}
}