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

Commit 0a1abd32 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Have RT drive window positioning"

parents 57218cbb f648108f
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -136,6 +136,9 @@ public class RenderNode {
    private RenderNode(String name, View owningView) {
    private RenderNode(String name, View owningView) {
        mNativeRenderNode = nCreate(name);
        mNativeRenderNode = nCreate(name);
        mOwningView = owningView;
        mOwningView = owningView;
        if (mOwningView instanceof SurfaceView) {
            nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView);
        }
    }
    }


    /**
    /**
@@ -863,6 +866,8 @@ public class RenderNode {
    private static native void nOutput(long renderNode);
    private static native void nOutput(long renderNode);
    private static native int nGetDebugSize(long renderNode);
    private static native int nGetDebugSize(long renderNode);


    private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback);

    ///////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////
    // Animations
    // Animations
    ///////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////
+73 −28
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ public class SurfaceView extends View {
        }
        }
    };
    };


    final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
    private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
            = new ViewTreeObserver.OnScrollChangedListener() {
            = new ViewTreeObserver.OnScrollChangedListener() {
                    @Override
                    @Override
                    public void onScrollChanged() {
                    public void onScrollChanged() {
@@ -143,6 +143,17 @@ public class SurfaceView extends View {
                    }
                    }
            };
            };


    private final ViewTreeObserver.OnPreDrawListener mDrawListener =
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // reposition ourselves where the surface is
                    mHaveFrame = getWidth() > 0 && getHeight() > 0;
                    updateWindow(false, false);
                    return true;
                }
            };

    boolean mRequestedVisible = false;
    boolean mRequestedVisible = false;
    boolean mWindowVisibility = false;
    boolean mWindowVisibility = false;
    boolean mViewVisibility = false;
    boolean mViewVisibility = false;
@@ -168,17 +179,9 @@ public class SurfaceView extends View {
    boolean mUpdateWindowNeeded;
    boolean mUpdateWindowNeeded;
    boolean mReportDrawNeeded;
    boolean mReportDrawNeeded;
    private Translator mTranslator;
    private Translator mTranslator;
    private int mWindowInsetLeft;
    private int mWindowInsetTop;


    private final ViewTreeObserver.OnPreDrawListener mDrawListener =
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // reposition ourselves where the surface is
                    mHaveFrame = getWidth() > 0 && getHeight() > 0;
                    updateWindow(false, false);
                    return true;
                }
            };
    private boolean mGlobalListenersAdded;
    private boolean mGlobalListenersAdded;


    public SurfaceView(Context context) {
    public SurfaceView(Context context) {
@@ -443,17 +446,17 @@ public class SurfaceView extends View {
        int myHeight = mRequestedHeight;
        int myHeight = mRequestedHeight;
        if (myHeight <= 0) myHeight = getHeight();
        if (myHeight <= 0) myHeight = getHeight();


        getLocationInWindow(mLocation);
        final boolean creating = mWindow == null;
        final boolean creating = mWindow == null;
        final boolean formatChanged = mFormat != mRequestedFormat;
        final boolean formatChanged = mFormat != mRequestedFormat;
        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
        final boolean visibleChanged = mVisible != mRequestedVisible;
        final boolean visibleChanged = mVisible != mRequestedVisible;
        final boolean layoutSizeChanged = getWidth() != mLayout.width
        final boolean layoutSizeChanged = getWidth() != mLayout.width
                || getHeight() != mLayout.height;
                || getHeight() != mLayout.height;
        final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1];


        if (force || creating || formatChanged || sizeChanged || visibleChanged
        if (force || creating || formatChanged || sizeChanged || visibleChanged
            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
            getLocationInWindow(mLocation);

            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                    + " format=" + formatChanged + " size=" + sizeChanged
                    + " format=" + formatChanged + " size=" + sizeChanged
                    + " visible=" + visibleChanged
                    + " visible=" + visibleChanged
@@ -643,7 +646,11 @@ public class SurfaceView extends View {
                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                " w=" + mLayout.width + " h=" + mLayout.height +
                " w=" + mLayout.width + " h=" + mLayout.height +
                ", frame=" + mSurfaceFrame);
                ", frame=" + mSurfaceFrame);
        } else if (positionChanged || layoutSizeChanged) { // Only the position has changed
        } else if (!isHardwareAccelerated()) {
            getLocationInWindow(mLocation);
            final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
                    || mWindowSpaceTop != mLocation[1];
            if (positionChanged || layoutSizeChanged) { // Only the position has changed
                mWindowSpaceLeft = mLocation[0];
                mWindowSpaceLeft = mLocation[0];
                mWindowSpaceTop = mLocation[1];
                mWindowSpaceTop = mLocation[1];
                // For our size changed check, we keep mLayout.width and mLayout.height
                // For our size changed check, we keep mLayout.width and mLayout.height
@@ -654,15 +661,53 @@ public class SurfaceView extends View {
                transformFromViewToWindowSpace(mLocation);
                transformFromViewToWindowSpace(mLocation);


                try {
                try {
                    Log.d(TAG, String.format("updateWindowPosition UI, " +
                            "postion = [%d, %d, %d, %d]", mWindowSpaceLeft, mWindowSpaceTop,
                            mLocation[0], mLocation[1]));
                    mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop,
                    mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop,
                        mLocation[0], mLocation[1],
                            mLocation[0], mLocation[1], -1, mWinFrame);
                        viewRoot != null ? viewRoot.getNextFrameNumber() : -1,
                        mWinFrame);
                } catch (RemoteException ex) {
                } catch (RemoteException ex) {
                    Log.e(TAG, "Exception from relayout", ex);
                    Log.e(TAG, "Exception from relayout", ex);
                }
                }
            }
            }
        }
        }
    }

    private Rect mRTLastReportedPosition = new Rect();

    /**
     * Called by native on RenderThread to update the window position
     * @hide
     */
    public final void updateWindowPositionRT(long frameNumber,
            int left, int top, int right, int bottom) {
        IWindowSession session = mSession;
        MyWindow window = mWindow;
        if (session == null || window == null) {
            // Guess we got detached, that sucks
            return;
        }
        if (mRTLastReportedPosition.left == left
                && mRTLastReportedPosition.top == top
                && mRTLastReportedPosition.right == right
                && mRTLastReportedPosition.bottom == bottom) {
            return;
        }
        try {
            if (DEBUG) {
                Log.d(TAG, String.format("updateWindowPosition RT, frameNr = %d, " +
                        "postion = [%d, %d, %d, %d]", frameNumber, left, top,
                        right, bottom));
            }
            // Just using mRTLastReportedPosition as a dummy rect here
            session.repositionChild(window, left, top, right, bottom, frameNumber,
                    mRTLastReportedPosition);
            // Now overwrite mRTLastReportedPosition with our values
            mRTLastReportedPosition.set(left, top, right, bottom);
        } catch (RemoteException ex) {
            Log.e(TAG, "Exception from repositionChild", ex);
        }
    }


    private SurfaceHolder.Callback[] getSurfaceCallbacks() {
    private SurfaceHolder.Callback[] getSurfaceCallbacks() {
        SurfaceHolder.Callback callbacks[];
        SurfaceHolder.Callback callbacks[];
+0 −14
Original line number Original line Diff line number Diff line
@@ -6815,20 +6815,6 @@ public final class ViewRootImpl implements ViewParent,
        }
        }
    }
    }


    long getNextFrameNumber() {
        long frameNumber = -1;
        if (mSurfaceHolder != null) {
            mSurfaceHolder.mSurfaceLock.lock();
        }
        if (mSurface.isValid()) {
            frameNumber =  mSurface.getNextFrameNumber();
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder.mSurfaceLock.unlock();
        }
        return frameNumber;
    }

    class TakenSurfaceHolder extends BaseSurfaceHolder {
    class TakenSurfaceHolder extends BaseSurfaceHolder {
        @Override
        @Override
        public boolean onAllowLockCanvas() {
        public boolean onAllowLockCanvas() {
+72 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */


#define LOG_TAG "OpenGLRenderer"
#define LOG_TAG "OpenGLRenderer"
#define ATRACE_TAG ATRACE_TAG_VIEW


#include <EGL/egl.h>
#include <EGL/egl.h>


@@ -24,7 +25,10 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/AndroidRuntime.h>


#include <Animator.h>
#include <Animator.h>
#include <DamageAccumulator.h>
#include <Matrix.h>
#include <RenderNode.h>
#include <RenderNode.h>
#include <TreeInfo.h>
#include <Paint.h>
#include <Paint.h>


#include "core_jni_helpers.h"
#include "core_jni_helpers.h"
@@ -461,6 +465,69 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
    renderNode->animators().endAllStagingAnimators();
    renderNode->animators().endAllStagingAnimators();
}
}


// ----------------------------------------------------------------------------
// SurfaceView position callback
// ----------------------------------------------------------------------------

jmethodID gSurfaceViewPositionUpdateMethod;

static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
        jlong renderNodePtr, jobject surfaceview) {
    class SurfaceViewPositionUpdater : public RenderNode::PositionListener {
    public:
        SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) {
            env->GetJavaVM(&mVm);
            mWeakRef = env->NewWeakGlobalRef(surfaceview);
        }

        virtual ~SurfaceViewPositionUpdater() {
            jnienv()->DeleteWeakGlobalRef(mWeakRef);
            mWeakRef = nullptr;
        }

        virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override {
            if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return;
            ATRACE_NAME("Update SurfaceView position");

            JNIEnv* env = jnienv();
            jobject localref = env->NewLocalRef(mWeakRef);
            if (CC_UNLIKELY(!localref)) {
                jnienv()->DeleteWeakGlobalRef(mWeakRef);
                mWeakRef = nullptr;
                return;
            }
            Matrix4 transform;
            info.damageAccumulator->computeCurrentTransform(&transform);
            const RenderProperties& props = node.properties();
            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
            transform.mapRect(bounds);
            bounds.left -= info.windowInsetLeft;
            bounds.right -= info.windowInsetLeft;
            bounds.top -= info.windowInsetTop;
            bounds.bottom -= info.windowInsetTop;
            env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod,
                    (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top,
                    (jint) bounds.right, (jint) bounds.bottom);
            env->DeleteLocalRef(localref);
        }

    private:
        JNIEnv* jnienv() {
            JNIEnv* env;
            if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
                LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm);
            }
            return env;
        }

        JavaVM* mVm;
        jobject mWeakRef;
    };

    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview));
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// JNI Glue
// JNI Glue
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -539,9 +606,14 @@ static const JNINativeMethod gMethods[] = {


    { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
    { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
    { "nEndAllAnimators",          "(J)V", (void*) android_view_RenderNode_endAllAnimators },
    { "nEndAllAnimators",          "(J)V", (void*) android_view_RenderNode_endAllAnimators },

    { "nRequestPositionUpdates",   "(JLandroid/view/SurfaceView;)V", (void*) android_view_RenderNode_requestPositionUpdates },
};
};


int register_android_view_RenderNode(JNIEnv* env) {
int register_android_view_RenderNode(JNIEnv* env) {
    jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
    gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
            "updateWindowPositionRT", "(JIIII)V");
    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}
}


+15 −8
Original line number Original line Diff line number Diff line
@@ -134,7 +134,14 @@ public:


    virtual void prepareTree(TreeInfo& info) {
    virtual void prepareTree(TreeInfo& info) {
        info.errorHandler = this;
        info.errorHandler = this;
        // TODO: This is hacky
        info.windowInsetLeft = -stagingProperties().getLeft();
        info.windowInsetTop = -stagingProperties().getTop();
        info.updateWindowPositions = true;
        RenderNode::prepareTree(info);
        RenderNode::prepareTree(info);
        info.updateWindowPositions = false;
        info.windowInsetLeft = 0;
        info.windowInsetTop = 0;
        info.errorHandler = NULL;
        info.errorHandler = NULL;
    }
    }


@@ -369,28 +376,28 @@ static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz,
static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
        jlong proxyPtr, jobject jsurface) {
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
    sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
    proxy->initialize(window);
    proxy->initialize(surface);
}
}


static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
        jlong proxyPtr, jobject jsurface) {
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window;
    sp<Surface> surface;
    if (jsurface) {
    if (jsurface) {
        window = android_view_Surface_getNativeWindow(env, jsurface);
        surface = android_view_Surface_getSurface(env, jsurface);
    }
    }
    proxy->updateSurface(window);
    proxy->updateSurface(surface);
}
}


static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
        jlong proxyPtr, jobject jsurface) {
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window;
    sp<Surface> surface;
    if (jsurface) {
    if (jsurface) {
        window = android_view_Surface_getNativeWindow(env, jsurface);
        surface = android_view_Surface_getSurface(env, jsurface);
    }
    }
    return proxy->pauseSurface(window);
    return proxy->pauseSurface(surface);
}
}


static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
Loading