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

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

Merge "Modernize RenderNode JNI"

parents 026ef6c1 395e9b8d
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) {