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

Commit 395e9b8d authored by John Reck's avatar John Reck
Browse files

Modernize RenderNode JNI

Change-Id: I455271647f01f3ac8ceb73359a51a2d2720fdd47
parent 793075b3
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.graphics.perftests;

import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.filters.LargeTest;
import android.view.RenderNode;

import org.junit.Rule;
import org.junit.Test;

@LargeTest
public class RenderNodePerfTest {
    @Rule
    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();

    @Test
    public void testMeasureRenderNodeJniOverhead() {
        RenderNode node = RenderNode.create("benchmark", null);
        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();

        while (state.keepRunning()) {
            node.setTranslationX(1.0f);
        }
    }
}
+81 −25
Original line number Diff line number Diff line
@@ -24,6 +24,10 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AnimatedVectorDrawable;

import dalvik.annotation.optimization.FastNative;

import libcore.util.NativeAllocationRegistry;

/**
 * <p>A display list records a series of graphics related operations and can replay
 * them later. Display lists are usually built by recording operations on a
@@ -128,6 +132,12 @@ import android.graphics.drawable.AnimatedVectorDrawable;
 */
public class RenderNode {

 // Use a Holder to allow static initialization in the boot image.
    private static class NoImagePreloadHolder {
        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
            RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
    }

    private boolean mValid;
    // Do not access directly unless you are ThreadedRenderer
    final long mNativeRenderNode;
@@ -135,6 +145,7 @@ public class RenderNode {

    private RenderNode(String name, View owningView) {
        mNativeRenderNode = nCreate(name);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
        mOwningView = owningView;
        if (mOwningView instanceof SurfaceView) {
            nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView);
@@ -145,6 +156,7 @@ public class RenderNode {
     * @see RenderNode#adopt(long)
     */
    private RenderNode(long nativePtr) {
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, nativePtr);
        mNativeRenderNode = nativePtr;
        mOwningView = null;
    }
@@ -812,99 +824,143 @@ public class RenderNode {
    // Intentionally not static because it acquires a reference to 'this'
    private native long nCreate(String name);

    private static native void nDestroyRenderNode(long renderNode);
    private static native long nGetNativeFinalizer();
    private static native void nSetDisplayList(long renderNode, long newData);
    private static native void nOutput(long renderNode);
    private static native int nGetDebugSize(long renderNode);
    private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback);

    // Animations

    private static native void nAddAnimator(long renderNode, long animatorPtr);
    private static native void nEndAllAnimators(long renderNode);

    ///////////////////////////////////////////////////////////////////////////
    // Fast native methods
    ///////////////////////////////////////////////////////////////////////////

    // Matrix

    @FastNative
    private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
    @FastNative
    private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
    @FastNative
    private static native boolean nHasIdentityMatrix(long renderNode);

    // Properties

    @FastNative
    private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
    @FastNative
    private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
    @FastNative
    private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
            int right, int bottom);
    @FastNative
    private static native boolean nSetBottom(long renderNode, int bottom);
    @FastNative
    private static native boolean nSetRight(long renderNode, int right);
    @FastNative
    private static native boolean nSetTop(long renderNode, int top);
    @FastNative
    private static native boolean nSetLeft(long renderNode, int left);
    @FastNative
    private static native boolean nSetCameraDistance(long renderNode, float distance);
    @FastNative
    private static native boolean nSetPivotY(long renderNode, float pivotY);
    @FastNative
    private static native boolean nSetPivotX(long renderNode, float pivotX);
    @FastNative
    private static native boolean nSetLayerType(long renderNode, int layerType);
    @FastNative
    private static native boolean nSetLayerPaint(long renderNode, long paint);
    @FastNative
    private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
    @FastNative
    private static native boolean nSetClipBounds(long renderNode, int left, int top,
            int right, int bottom);
    @FastNative
    private static native boolean nSetClipBoundsEmpty(long renderNode);
    @FastNative
    private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
    @FastNative
    private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
    @FastNative
    private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
            int right, int bottom, float radius, float alpha);
    @FastNative
    private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
            float alpha);
    @FastNative
    private static native boolean nSetOutlineEmpty(long renderNode);
    @FastNative
    private static native boolean nSetOutlineNone(long renderNode);
    @FastNative
    private static native boolean nHasShadow(long renderNode);
    @FastNative
    private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
    @FastNative
    private static native boolean nSetRevealClip(long renderNode,
            boolean shouldClip, float x, float y, float radius);
    @FastNative
    private static native boolean nSetAlpha(long renderNode, float alpha);
    @FastNative
    private static native boolean nSetHasOverlappingRendering(long renderNode,
            boolean hasOverlappingRendering);
    @FastNative
    private static native boolean nSetElevation(long renderNode, float lift);
    @FastNative
    private static native boolean nSetTranslationX(long renderNode, float translationX);
    @FastNative
    private static native boolean nSetTranslationY(long renderNode, float translationY);
    @FastNative
    private static native boolean nSetTranslationZ(long renderNode, float translationZ);
    @FastNative
    private static native boolean nSetRotation(long renderNode, float rotation);
    @FastNative
    private static native boolean nSetRotationX(long renderNode, float rotationX);
    @FastNative
    private static native boolean nSetRotationY(long renderNode, float rotationY);
    @FastNative
    private static native boolean nSetScaleX(long renderNode, float scaleX);
    @FastNative
    private static native boolean nSetScaleY(long renderNode, float scaleY);
    @FastNative
    private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
    @FastNative
    private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);

    @FastNative
    private static native boolean nHasOverlappingRendering(long renderNode);
    @FastNative
    private static native boolean nGetClipToOutline(long renderNode);
    @FastNative
    private static native float nGetAlpha(long renderNode);
    @FastNative
    private static native float nGetCameraDistance(long renderNode);
    @FastNative
    private static native float nGetScaleX(long renderNode);
    @FastNative
    private static native float nGetScaleY(long renderNode);
    @FastNative
    private static native float nGetElevation(long renderNode);
    @FastNative
    private static native float nGetTranslationX(long renderNode);
    @FastNative
    private static native float nGetTranslationY(long renderNode);
    @FastNative
    private static native float nGetTranslationZ(long renderNode);
    @FastNative
    private static native float nGetRotation(long renderNode);
    @FastNative
    private static native float nGetRotationX(long renderNode);
    @FastNative
    private static native float nGetRotationY(long renderNode);
    @FastNative
    private static native boolean nIsPivotExplicitlySet(long renderNode);
    @FastNative
    private static native float nGetPivotX(long renderNode);
    @FastNative
    private static native float nGetPivotY(long 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
    ///////////////////////////////////////////////////////////////////////////

    private static native void nAddAnimator(long renderNode, long animatorPtr);
    private static native void nEndAllAnimators(long renderNode);

    ///////////////////////////////////////////////////////////////////////////
    // Finalization
    ///////////////////////////////////////////////////////////////////////////

    @Override
    protected void finalize() throws Throwable {
        try {
            nDestroyRenderNode(mNativeRenderNode);
        } finally {
            super.finalize();
        }
    }
}
+76 −69
Original line number Diff line number Diff line
@@ -120,12 +120,15 @@ static jlong android_view_RenderNode_create(JNIEnv* env, jobject thiz,
    return reinterpret_cast<jlong>(renderNode);
}

static void android_view_RenderNode_destroyRenderNode(JNIEnv* env,
        jobject clazz, jlong renderNodePtr) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
static void releaseRenderNode(RenderNode* renderNode) {
    renderNode->decStrong(0);
}

static jlong android_view_RenderNode_getNativeFinalizer(JNIEnv* env,
        jobject clazz) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseRenderNode));
}

static void android_view_RenderNode_setDisplayList(JNIEnv* env,
        jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
    class RemovedObserver : public TreeObserver {
@@ -643,79 +646,83 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
const char* const kClassPathName = "android/view/RenderNode";

static const JNINativeMethod gMethods[] = {
// ----------------------------------------------------------------------------
// Regular JNI
// ----------------------------------------------------------------------------
    { "nCreate",               "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
    { "nDestroyRenderNode",    "(J)V",    (void*) android_view_RenderNode_destroyRenderNode },
    { "nGetNativeFinalizer",   "()J",    (void*) android_view_RenderNode_getNativeFinalizer },
    { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
    { "nOutput",               "(J)V",    (void*) android_view_RenderNode_output },
    { "nGetDebugSize",         "(J)I",    (void*) android_view_RenderNode_getDebugSize },

    { "nSetLayerType",         "!(JI)Z",  (void*) android_view_RenderNode_setLayerType },
    { "nSetLayerPaint",        "!(JJ)Z",  (void*) android_view_RenderNode_setLayerPaint },
    { "nSetStaticMatrix",      "!(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
    { "nSetAnimationMatrix",   "!(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
    { "nSetClipToBounds",      "!(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
    { "nSetClipBounds",        "!(JIIII)Z", (void*) android_view_RenderNode_setClipBounds },
    { "nSetClipBoundsEmpty",   "!(J)Z",   (void*) android_view_RenderNode_setClipBoundsEmpty },
    { "nSetProjectBackwards",  "!(JZ)Z",  (void*) android_view_RenderNode_setProjectBackwards },
    { "nSetProjectionReceiver","!(JZ)Z",  (void*) android_view_RenderNode_setProjectionReceiver },

    { "nSetOutlineRoundRect",  "!(JIIIIFF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
    { "nSetOutlineConvexPath", "!(JJF)Z", (void*) android_view_RenderNode_setOutlineConvexPath },
    { "nSetOutlineEmpty",      "!(J)Z",   (void*) android_view_RenderNode_setOutlineEmpty },
    { "nSetOutlineNone",       "!(J)Z",   (void*) android_view_RenderNode_setOutlineNone },
    { "nHasShadow",            "!(J)Z",   (void*) android_view_RenderNode_hasShadow },
    { "nSetClipToOutline",     "!(JZ)Z",  (void*) android_view_RenderNode_setClipToOutline },
    { "nSetRevealClip",        "!(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip },

    { "nSetAlpha",             "!(JF)Z",  (void*) android_view_RenderNode_setAlpha },
    { "nSetHasOverlappingRendering", "!(JZ)Z",
            (void*) android_view_RenderNode_setHasOverlappingRendering },
    { "nSetElevation",         "!(JF)Z",  (void*) android_view_RenderNode_setElevation },
    { "nSetTranslationX",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationX },
    { "nSetTranslationY",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationY },
    { "nSetTranslationZ",      "!(JF)Z",  (void*) android_view_RenderNode_setTranslationZ },
    { "nSetRotation",          "!(JF)Z",  (void*) android_view_RenderNode_setRotation },
    { "nSetRotationX",         "!(JF)Z",  (void*) android_view_RenderNode_setRotationX },
    { "nSetRotationY",         "!(JF)Z",  (void*) android_view_RenderNode_setRotationY },
    { "nSetScaleX",            "!(JF)Z",  (void*) android_view_RenderNode_setScaleX },
    { "nSetScaleY",            "!(JF)Z",  (void*) android_view_RenderNode_setScaleY },
    { "nSetPivotX",            "!(JF)Z",  (void*) android_view_RenderNode_setPivotX },
    { "nSetPivotY",            "!(JF)Z",  (void*) android_view_RenderNode_setPivotY },
    { "nSetCameraDistance",    "!(JF)Z",  (void*) android_view_RenderNode_setCameraDistance },
    { "nSetLeft",              "!(JI)Z",  (void*) android_view_RenderNode_setLeft },
    { "nSetTop",               "!(JI)Z",  (void*) android_view_RenderNode_setTop },
    { "nSetRight",             "!(JI)Z",  (void*) android_view_RenderNode_setRight },
    { "nSetBottom",            "!(JI)Z",  (void*) android_view_RenderNode_setBottom },
    { "nSetLeftTopRightBottom","!(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
    { "nOffsetLeftAndRight",   "!(JI)Z",  (void*) android_view_RenderNode_offsetLeftAndRight },
    { "nOffsetTopAndBottom",   "!(JI)Z",  (void*) android_view_RenderNode_offsetTopAndBottom },

    { "nHasOverlappingRendering", "!(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
    { "nGetClipToOutline",        "!(J)Z",  (void*) android_view_RenderNode_getClipToOutline },
    { "nGetAlpha",                "!(J)F",  (void*) android_view_RenderNode_getAlpha },
    { "nGetCameraDistance",       "!(J)F",  (void*) android_view_RenderNode_getCameraDistance },
    { "nGetScaleX",               "!(J)F",  (void*) android_view_RenderNode_getScaleX },
    { "nGetScaleY",               "!(J)F",  (void*) android_view_RenderNode_getScaleY },
    { "nGetElevation",            "!(J)F",  (void*) android_view_RenderNode_getElevation },
    { "nGetTranslationX",         "!(J)F",  (void*) android_view_RenderNode_getTranslationX },
    { "nGetTranslationY",         "!(J)F",  (void*) android_view_RenderNode_getTranslationY },
    { "nGetTranslationZ",         "!(J)F",  (void*) android_view_RenderNode_getTranslationZ },
    { "nGetRotation",             "!(J)F",  (void*) android_view_RenderNode_getRotation },
    { "nGetRotationX",            "!(J)F",  (void*) android_view_RenderNode_getRotationX },
    { "nGetRotationY",            "!(J)F",  (void*) android_view_RenderNode_getRotationY },
    { "nIsPivotExplicitlySet",    "!(J)Z",  (void*) android_view_RenderNode_isPivotExplicitlySet },
    { "nHasIdentityMatrix",       "!(J)Z",  (void*) android_view_RenderNode_hasIdentityMatrix },

    { "nGetTransformMatrix",       "!(JJ)V", (void*) android_view_RenderNode_getTransformMatrix },
    { "nGetInverseTransformMatrix","!(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix },

    { "nGetPivotX",                "!(J)F",  (void*) android_view_RenderNode_getPivotX },
    { "nGetPivotY",                "!(J)F",  (void*) android_view_RenderNode_getPivotY },

    { "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 },

// ----------------------------------------------------------------------------
// Fast JNI via @FastNative annotation in RenderNode.java
// ----------------------------------------------------------------------------
    { "nSetLayerType",         "(JI)Z",  (void*) android_view_RenderNode_setLayerType },
    { "nSetLayerPaint",        "(JJ)Z",  (void*) android_view_RenderNode_setLayerPaint },
    { "nSetStaticMatrix",      "(JJ)Z",  (void*) android_view_RenderNode_setStaticMatrix },
    { "nSetAnimationMatrix",   "(JJ)Z",  (void*) android_view_RenderNode_setAnimationMatrix },
    { "nSetClipToBounds",      "(JZ)Z",  (void*) android_view_RenderNode_setClipToBounds },
    { "nSetClipBounds",        "(JIIII)Z", (void*) android_view_RenderNode_setClipBounds },
    { "nSetClipBoundsEmpty",   "(J)Z",   (void*) android_view_RenderNode_setClipBoundsEmpty },
    { "nSetProjectBackwards",  "(JZ)Z",  (void*) android_view_RenderNode_setProjectBackwards },
    { "nSetProjectionReceiver","(JZ)Z",  (void*) android_view_RenderNode_setProjectionReceiver },

    { "nSetOutlineRoundRect",  "(JIIIIFF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
    { "nSetOutlineConvexPath", "(JJF)Z", (void*) android_view_RenderNode_setOutlineConvexPath },
    { "nSetOutlineEmpty",      "(J)Z",   (void*) android_view_RenderNode_setOutlineEmpty },
    { "nSetOutlineNone",       "(J)Z",   (void*) android_view_RenderNode_setOutlineNone },
    { "nHasShadow",            "(J)Z",   (void*) android_view_RenderNode_hasShadow },
    { "nSetClipToOutline",     "(JZ)Z",  (void*) android_view_RenderNode_setClipToOutline },
    { "nSetRevealClip",        "(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip },

    { "nSetAlpha",             "(JF)Z",  (void*) android_view_RenderNode_setAlpha },
    { "nSetHasOverlappingRendering", "(JZ)Z",
            (void*) android_view_RenderNode_setHasOverlappingRendering },
    { "nSetElevation",         "(JF)Z",  (void*) android_view_RenderNode_setElevation },
    { "nSetTranslationX",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationX },
    { "nSetTranslationY",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationY },
    { "nSetTranslationZ",      "(JF)Z",  (void*) android_view_RenderNode_setTranslationZ },
    { "nSetRotation",          "(JF)Z",  (void*) android_view_RenderNode_setRotation },
    { "nSetRotationX",         "(JF)Z",  (void*) android_view_RenderNode_setRotationX },
    { "nSetRotationY",         "(JF)Z",  (void*) android_view_RenderNode_setRotationY },
    { "nSetScaleX",            "(JF)Z",  (void*) android_view_RenderNode_setScaleX },
    { "nSetScaleY",            "(JF)Z",  (void*) android_view_RenderNode_setScaleY },
    { "nSetPivotX",            "(JF)Z",  (void*) android_view_RenderNode_setPivotX },
    { "nSetPivotY",            "(JF)Z",  (void*) android_view_RenderNode_setPivotY },
    { "nSetCameraDistance",    "(JF)Z",  (void*) android_view_RenderNode_setCameraDistance },
    { "nSetLeft",              "(JI)Z",  (void*) android_view_RenderNode_setLeft },
    { "nSetTop",               "(JI)Z",  (void*) android_view_RenderNode_setTop },
    { "nSetRight",             "(JI)Z",  (void*) android_view_RenderNode_setRight },
    { "nSetBottom",            "(JI)Z",  (void*) android_view_RenderNode_setBottom },
    { "nSetLeftTopRightBottom","(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
    { "nOffsetLeftAndRight",   "(JI)Z",  (void*) android_view_RenderNode_offsetLeftAndRight },
    { "nOffsetTopAndBottom",   "(JI)Z",  (void*) android_view_RenderNode_offsetTopAndBottom },

    { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
    { "nGetClipToOutline",        "(J)Z",  (void*) android_view_RenderNode_getClipToOutline },
    { "nGetAlpha",                "(J)F",  (void*) android_view_RenderNode_getAlpha },
    { "nGetCameraDistance",       "(J)F",  (void*) android_view_RenderNode_getCameraDistance },
    { "nGetScaleX",               "(J)F",  (void*) android_view_RenderNode_getScaleX },
    { "nGetScaleY",               "(J)F",  (void*) android_view_RenderNode_getScaleY },
    { "nGetElevation",            "(J)F",  (void*) android_view_RenderNode_getElevation },
    { "nGetTranslationX",         "(J)F",  (void*) android_view_RenderNode_getTranslationX },
    { "nGetTranslationY",         "(J)F",  (void*) android_view_RenderNode_getTranslationY },
    { "nGetTranslationZ",         "(J)F",  (void*) android_view_RenderNode_getTranslationZ },
    { "nGetRotation",             "(J)F",  (void*) android_view_RenderNode_getRotation },
    { "nGetRotationX",            "(J)F",  (void*) android_view_RenderNode_getRotationX },
    { "nGetRotationY",            "(J)F",  (void*) android_view_RenderNode_getRotationY },
    { "nIsPivotExplicitlySet",    "(J)Z",  (void*) android_view_RenderNode_isPivotExplicitlySet },
    { "nHasIdentityMatrix",       "(J)Z",  (void*) android_view_RenderNode_hasIdentityMatrix },

    { "nGetTransformMatrix",       "(JJ)V", (void*) android_view_RenderNode_getTransformMatrix },
    { "nGetInverseTransformMatrix","(JJ)V", (void*) android_view_RenderNode_getInverseTransformMatrix },

    { "nGetPivotX",                "(J)F",  (void*) android_view_RenderNode_getPivotX },
    { "nGetPivotY",                "(J)F",  (void*) android_view_RenderNode_getPivotY },
};

int register_android_view_RenderNode(JNIEnv* env) {