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

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

Merge "Add benchmarks for View inflation"

parents 3f2e215c 3acf0382
Loading
Loading
Loading
Loading
+20 −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.
-->

<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/simple_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
+29 −2
Original line number Diff line number Diff line
@@ -31,11 +31,38 @@ public class RenderNodePerfTest {

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

        while (state.keepRunning()) {
            node.setTranslationX(1.0f);
        }
    }

    @Test
    public void testCreateRenderNodeNoName() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            RenderNode node = RenderNode.create(null, null);
            node.destroy();
        }
    }

    @Test
    public void testCreateRenderNode() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            RenderNode node = RenderNode.create("LinearLayout", null);
            node.destroy();
        }
    }

    @Test
    public void testIsValid() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        RenderNode node = RenderNode.create("LinearLayout", null);
        while (state.keepRunning()) {
            node.isValid();
        }
    }
}
+47 −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.view;

import android.content.Context;
import android.content.res.Resources;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.widget.FrameLayout;

import com.android.perftests.core.R;

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

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

    @Test
    public void testSimpleViewInflate() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        FrameLayout root = new FrameLayout(context);
        while (state.keepRunning()) {
            inflater.inflate(R.layout.test_simple_view, root, false);
        }
    }
}
+12 −0
Original line number Diff line number Diff line
@@ -19,8 +19,11 @@ package android.perftests.utils;
import android.app.Activity;
import android.app.Instrumentation;
import android.os.Bundle;
import android.os.Debug;
import android.support.test.InstrumentationRegistry;
import android.util.Log;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
@@ -45,6 +48,7 @@ import java.util.concurrent.TimeUnit;
public final class BenchmarkState {

    private static final String TAG = "BenchmarkState";
    private static final boolean ENABLE_PROFILING = false;

    private static final int NOT_STARTED = 0;  // The benchmark has not started yet.
    private static final int WARMUP = 1; // The benchmark is warming up.
@@ -146,6 +150,11 @@ public final class BenchmarkState {
    }

    private void beginBenchmark(long warmupDuration, int iterations) {
        if (ENABLE_PROFILING) {
            File f = new File(InstrumentationRegistry.getContext().getDataDir(), "benchprof");
            Log.d(TAG, "Tracing to: " + f.getAbsolutePath());
            Debug.startMethodTracingSampling(f.getAbsolutePath(), 16 * 1024 * 1024, 100);
        }
        mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
        mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
                Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
@@ -161,6 +170,9 @@ public final class BenchmarkState {
        mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations);
        mRepeatCount++;
        if (mRepeatCount >= REPEAT_COUNT) {
            if (ENABLE_PROFILING) {
                Debug.stopMethodTracing();
            }
            calculateSatistics();
            mState = FINISHED;
            return false;
+30 −17
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@ 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
@@ -132,35 +130,45 @@ import libcore.util.NativeAllocationRegistry;
 */
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;
    long mNativeRenderNode;
    private final View mOwningView;

    private RenderNode(String name, View owningView) {
        mNativeRenderNode = nCreate(name);
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
        mOwningView = owningView;
        if (mOwningView instanceof SurfaceView) {
            nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView);
        }
    }

    /**
     * @see RenderNode#adopt(long)
     */
    private RenderNode(long nativePtr) {
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, nativePtr);
        mNativeRenderNode = nativePtr;
        mOwningView = null;
    }

    /**
     * Immediately destroys the RenderNode
     * Only suitable for testing/benchmarking where waiting for the GC/finalizer
     * is not feasible.
     */
    public void destroy() {
        if (mNativeRenderNode != 0) {
            nFinalize(mNativeRenderNode);
            mNativeRenderNode = 0;
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            destroy();
        } finally {
            super.finalize();
        }
    }

    /**
     * Creates a new RenderNode that can be used to record batches of
     * drawing operations, and store / apply render properties when drawn.
@@ -183,6 +191,13 @@ public class RenderNode {
        return new RenderNode(nativePtr);
    }

    /**
     * Enable callbacks for position changes.
     */
    public void requestPositionUpdates(SurfaceView view) {
        nRequestPositionUpdates(mNativeRenderNode, view);
    }


    /**
     * Starts recording a display list for the render node. All
@@ -784,9 +799,6 @@ public class RenderNode {
     */
    void onRenderNodeDetached() {
        discardDisplayList();
        if (mOwningView != null) {
            mOwningView.onRenderNodeDetached(this);
        }
    }

    ///////////////////////////////////////////////////////////////////////////
@@ -823,6 +835,7 @@ public class RenderNode {

    // Intentionally not static because it acquires a reference to 'this'
    private native long nCreate(String name);
    private native void nFinalize(long renderNode);

    private static native long nGetNativeFinalizer();
    private static native void nSetDisplayList(long renderNode, long newData);
Loading