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 Diff line number Diff line
@@ -136,6 +136,9 @@ public class RenderNode {
    private RenderNode(String name, View owningView) {
        mNativeRenderNode = nCreate(name);
        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 int nGetDebugSize(long renderNode);

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

    ///////////////////////////////////////////////////////////////////////////
    // Animations
    ///////////////////////////////////////////////////////////////////////////
+73 −28
Original line number 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() {
                    @Override
                    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 mWindowVisibility = false;
    boolean mViewVisibility = false;
@@ -168,17 +179,9 @@ public class SurfaceView extends View {
    boolean mUpdateWindowNeeded;
    boolean mReportDrawNeeded;
    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;

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

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

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

            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                    + " format=" + formatChanged + " size=" + sizeChanged
                    + " visible=" + visibleChanged
@@ -643,7 +646,11 @@ public class SurfaceView extends View {
                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                " w=" + mLayout.width + " h=" + mLayout.height +
                ", 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];
                mWindowSpaceTop = mLocation[1];
                // For our size changed check, we keep mLayout.width and mLayout.height
@@ -654,15 +661,53 @@ public class SurfaceView extends View {
                transformFromViewToWindowSpace(mLocation);

                try {
                    Log.d(TAG, String.format("updateWindowPosition UI, " +
                            "postion = [%d, %d, %d, %d]", mWindowSpaceLeft, mWindowSpaceTop,
                            mLocation[0], mLocation[1]));
                    mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop,
                        mLocation[0], mLocation[1],
                        viewRoot != null ? viewRoot.getNextFrameNumber() : -1,
                        mWinFrame);
                            mLocation[0], mLocation[1], -1, mWinFrame);
                } catch (RemoteException 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() {
        SurfaceHolder.Callback callbacks[];
+0 −14
Original line number 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 {
        @Override
        public boolean onAllowLockCanvas() {
+72 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#define LOG_TAG "OpenGLRenderer"
#define ATRACE_TAG ATRACE_TAG_VIEW

#include <EGL/egl.h>

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

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

#include "core_jni_helpers.h"
@@ -461,6 +465,69 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
    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
// ----------------------------------------------------------------------------
@@ -539,9 +606,14 @@ static const JNINativeMethod gMethods[] = {

    { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
    { "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) {
    jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
    gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
            "updateWindowPositionRT", "(JIIII)V");
    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}

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

    virtual void prepareTree(TreeInfo& info) {
        info.errorHandler = this;
        // TODO: This is hacky
        info.windowInsetLeft = -stagingProperties().getLeft();
        info.windowInsetTop = -stagingProperties().getTop();
        info.updateWindowPositions = true;
        RenderNode::prepareTree(info);
        info.updateWindowPositions = false;
        info.windowInsetLeft = 0;
        info.windowInsetTop = 0;
        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,
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
    proxy->initialize(window);
    sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
    proxy->initialize(surface);
}

static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window;
    sp<Surface> surface;
    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,
        jlong proxyPtr, jobject jsurface) {
    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
    sp<ANativeWindow> window;
    sp<Surface> surface;
    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,
Loading