summaryrefslogtreecommitdiff
path: root/graphics/java
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2019-12-09 12:38:59 -0500
committerDerek Sollenberger <djsollen@google.com>2019-12-17 10:15:27 -0500
commitc4ef2c702a744c8d0a918d5dceb8d88bf3713908 (patch)
tree61411e19e01ea94e4ef8b8f5887f56bf834f84b1 /graphics/java
parent3d559cbdc8788b790e932ce6b0cdf3e86e05246a (diff)
Move FrameMetricsObserver logic into UI Module.
Introduce HardwareRendererObserver to isolate the android.graphics package from the android.view package. The native code that interacts with the observer was also moved from libandroid_runtime to libandroid_graphics to keep it within the confines of the UI Rendering module. Bug: 137655431 Test: CtsUiRenderingTestCases Change-Id: Ibccecbeda0c4d9501d86514a53eb98548233ba6a
Diffstat (limited to 'graphics/java')
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java18
-rw-r--r--graphics/java/android/graphics/HardwareRendererObserver.java103
2 files changed, 109 insertions, 12 deletions
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 3f3ad578e8d7..3b864139cf71 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -28,7 +28,6 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.TimeUtils;
-import android.view.FrameMetricsObserver;
import android.view.IGraphicsStats;
import android.view.IGraphicsStatsCallback;
import android.view.NativeVectorDrawableAnimator;
@@ -38,8 +37,6 @@ import android.view.SurfaceHolder;
import android.view.TextureLayer;
import android.view.animation.AnimationUtils;
-import com.android.internal.util.VirtualRefBasePtr;
-
import java.io.File;
import java.io.FileDescriptor;
import java.lang.annotation.Retention;
@@ -598,9 +595,8 @@ public class HardwareRenderer {
*
* @hide
*/
- public void addFrameMetricsObserver(FrameMetricsObserver observer) {
- long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
- observer.mNative = new VirtualRefBasePtr(nativeObserver);
+ public void addObserver(HardwareRendererObserver observer) {
+ nAddObserver(mNativeProxy, observer.getNativeInstance());
}
/**
@@ -608,9 +604,8 @@ public class HardwareRenderer {
*
* @hide
*/
- public void removeFrameMetricsObserver(FrameMetricsObserver observer) {
- nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
- observer.mNative = null;
+ public void removeObserver(HardwareRendererObserver observer) {
+ nRemoveObserver(mNativeProxy, observer.getNativeInstance());
}
/**
@@ -1170,10 +1165,9 @@ public class HardwareRenderer {
private static native void nSetFrameCompleteCallback(long nativeProxy,
FrameCompleteCallback callback);
- private static native long nAddFrameMetricsObserver(long nativeProxy,
- FrameMetricsObserver observer);
+ private static native void nAddObserver(long nativeProxy, long nativeObserver);
- private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
+ private static native void nRemoveObserver(long nativeProxy, long nativeObserver);
private static native int nCopySurfaceInto(Surface surface,
int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle);
diff --git a/graphics/java/android/graphics/HardwareRendererObserver.java b/graphics/java/android/graphics/HardwareRendererObserver.java
new file mode 100644
index 000000000000..da9d03c639f7
--- /dev/null
+++ b/graphics/java/android/graphics/HardwareRendererObserver.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 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;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+
+import com.android.internal.util.VirtualRefBasePtr;
+
+/**
+ * Provides streaming access to frame stats information from HardwareRenderer to apps.
+ *
+ * @hide
+ */
+public class HardwareRendererObserver {
+ private final long[] mFrameMetrics;
+ private final Handler mHandler;
+ private final OnFrameMetricsAvailableListener mListener;
+ private VirtualRefBasePtr mNativePtr;
+
+ /**
+ * Interface for clients that want frame timing information for each frame rendered.
+ * @hide
+ */
+ public interface OnFrameMetricsAvailableListener {
+ /**
+ * Called when information is available for the previously rendered frame.
+ *
+ * Reports can be dropped if this callback takes too long to execute, as the report producer
+ * cannot wait for the consumer to complete.
+ *
+ * It is highly recommended that clients copy the metrics array within this method
+ * and defer additional computation or storage to another thread to avoid unnecessarily
+ * dropping reports.
+ *
+ * @param dropCountSinceLastInvocation the number of reports dropped since the last time
+ * this callback was invoked.
+ */
+ void onFrameMetricsAvailable(int dropCountSinceLastInvocation);
+ }
+
+ /**
+ * Creates a FrameMetricsObserver
+ *
+ * @param frameMetrics the available metrics. This array is reused on every call to the listener
+ * and thus <strong>this reference should only be used within the scope of the listener callback
+ * as data is not guaranteed to be valid outside the scope of that method</strong>.
+ * @param handler the Handler to use when invoking callbacks
+ */
+ public HardwareRendererObserver(@NonNull OnFrameMetricsAvailableListener listener,
+ @NonNull long[] frameMetrics, @NonNull Handler handler) {
+ if (handler == null || handler.getLooper() == null) {
+ throw new NullPointerException("handler and its looper cannot be null");
+ }
+
+ if (handler.getLooper().getQueue() == null) {
+ throw new IllegalStateException("invalid looper, null message queue\n");
+ }
+
+ mFrameMetrics = frameMetrics;
+ mHandler = handler;
+ mListener = listener;
+ mNativePtr = new VirtualRefBasePtr(nCreateObserver());
+ }
+
+ /*package*/ long getNativeInstance() {
+ return mNativePtr.get();
+ }
+
+ // Called by native on the provided Handler
+ @SuppressWarnings("unused")
+ private void notifyDataAvailable() {
+ mHandler.post(() -> {
+ boolean hasMoreData = true;
+ while (hasMoreData) {
+ // a drop count of -1 is a sentinel that no more buffers are available
+ int dropCount = nGetNextBuffer(mNativePtr.get(), mFrameMetrics);
+ if (dropCount >= 0) {
+ mListener.onFrameMetricsAvailable(dropCount);
+ } else {
+ hasMoreData = false;
+ }
+ }
+ });
+ }
+
+ private native long nCreateObserver();
+ private static native int nGetNextBuffer(long nativePtr, long[] data);
+}