diff options
| -rw-r--r-- | core/java/android/view/TextureView.java | 16 | ||||
| -rw-r--r-- | core/jni/android_graphics_SurfaceTexture.cpp | 21 | ||||
| -rw-r--r-- | graphics/java/android/graphics/SurfaceTexture.java | 90 |
3 files changed, 126 insertions, 1 deletions
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index bdd0a9cf653a..969b6a5125d0 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -16,6 +16,7 @@ package android.view; +import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -30,8 +31,10 @@ import android.graphics.SurfaceTexture; import android.graphics.TextureLayer; import android.graphics.drawable.Drawable; import android.os.Build; +import android.os.Trace; import android.util.AttributeSet; import android.util.Log; +import android.view.flags.Flags; /** * <p>A TextureView can be used to display a content stream, such as that @@ -194,6 +197,9 @@ public class TextureView extends View { private Canvas mCanvas; private int mSaveCount; + @FloatRange(from = 0.0) float mFrameRate; + @Surface.FrameRateCompatibility int mFrameRateCompatibility; + private final Object[] mNativeWindowLock = new Object[0]; // Set by native code, do not write! @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -465,6 +471,16 @@ public class TextureView extends View { mLayer.setSurfaceTexture(mSurface); mSurface.setDefaultBufferSize(getWidth(), getHeight()); mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); + if (Flags.toolkitSetFrameRate()) { + mSurface.setOnSetFrameRateListener( + (surfaceTexture, frameRate, compatibility, strategy) -> { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, "setFrameRate: " + frameRate); + } + mFrameRate = frameRate; + mFrameRateCompatibility = compatibility; + }, mAttachInfo.mHandler); + } if (mListener != null && createNewSurface) { mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight()); diff --git a/core/jni/android_graphics_SurfaceTexture.cpp b/core/jni/android_graphics_SurfaceTexture.cpp index 7b7ede092e57..50832a5c256a 100644 --- a/core/jni/android_graphics_SurfaceTexture.cpp +++ b/core/jni/android_graphics_SurfaceTexture.cpp @@ -24,7 +24,6 @@ #include <com_android_graphics_libgui_flags.h> #include <cutils/atomic.h> #include <gui/BufferQueue.h> -#include <gui/Flags.h> #include <gui/Surface.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> @@ -53,6 +52,7 @@ struct fields_t { jfieldID producer; jfieldID frameAvailableListener; jmethodID postEvent; + jmethodID postOnSetFrameRateEvent; }; static fields_t fields; @@ -196,9 +196,21 @@ class JNISurfaceTextureContextListener : public JNISurfaceTextureContextCommon, public: JNISurfaceTextureContextListener(JNIEnv* env, jobject weakThiz, jclass clazz) : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} + void onFrameAvailable(const BufferItem& item) override { JNISurfaceTextureContextCommon::onFrameAvailable(item); } + + void onSetFrameRate(float frameRate, int8_t compatibility, + int8_t changeFrameRateStrategy) override { + JNIEnv* env = getJNIEnv(); + if (env != NULL) { + env->CallStaticVoidMethod(mClazz, fields.postOnSetFrameRateEvent, mWeakThiz, frameRate, + compatibility, changeFrameRateStrategy); + } else { + ALOGW("onSetFrameRate event will not posted"); + } + } }; // ---------------------------------------------------------------------------- @@ -235,6 +247,13 @@ static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) if (fields.postEvent == NULL) { ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative"); } + + fields.postOnSetFrameRateEvent = + env->GetStaticMethodID(clazz, "postOnSetFrameRateEventFromNative", + "(Ljava/lang/ref/WeakReference;FII)V"); + if (fields.postOnSetFrameRateEvent == NULL) { + ALOGE("can't find android/graphics/SurfaceTexture.postOnSetFrameRateEventFromNative"); + } } static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached, diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index dfe5012a2b4d..dd82fed03087 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -16,6 +16,7 @@ package android.graphics; +import android.annotation.FloatRange; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; @@ -24,8 +25,10 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.Trace; import android.view.Surface; import android.view.TextureView; +import android.view.flags.Flags; import java.lang.ref.WeakReference; @@ -79,6 +82,7 @@ public class SurfaceTexture { private final Looper mCreatorLooper; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Handler mOnFrameAvailableHandler; + private Handler mOnSetFrameRateHandler; /** * These fields are used by native code, do not access or modify. @@ -100,6 +104,21 @@ public class SurfaceTexture { } /** + * Callback interface for being notified that a producer set a frame rate + * @hide + */ + public interface OnSetFrameRateListener { + /** + * Called when the producer sets a frame rate + * @hide + */ + void onSetFrameRate(SurfaceTexture surfaceTexture, + @FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy); + } + + /** * Exception thrown when a SurfaceTexture couldn't be created or resized. * * @deprecated No longer thrown. {@link android.view.Surface.OutOfResourcesException} @@ -224,6 +243,48 @@ public class SurfaceTexture { } } + private static class SetFrameRateArgs { + SetFrameRateArgs(@FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { + this.mFrameRate = frameRate; + this.mCompatibility = compatibility; + this.mChangeFrameRateStrategy = changeFrameRateStrategy; + } + final float mFrameRate; + final int mCompatibility; + final int mChangeFrameRateStrategy; + } + + /** + * Register a callback to be invoked when the producer sets a frame rate using + * Surface.setFrameRate. + * @hide + */ + public void setOnSetFrameRateListener(@Nullable final OnSetFrameRateListener listener, + @Nullable Handler handler) { + if (listener != null) { + Looper looper = handler != null ? handler.getLooper() : + mCreatorLooper != null ? mCreatorLooper : Looper.getMainLooper(); + mOnSetFrameRateHandler = new Handler(looper, null, true /*async*/) { + @Override + public void handleMessage(Message msg) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSetFrameRateHandler"); + try { + SetFrameRateArgs args = (SetFrameRateArgs) msg.obj; + listener.onSetFrameRate(SurfaceTexture.this, + args.mFrameRate, args.mCompatibility, + args.mChangeFrameRateStrategy); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + } + }; + } else { + mOnSetFrameRateHandler = null; + } + } + /** * Set the default size of the image buffers. The image producer may override the buffer size, * in which case the producer-set buffer size will be used, not the default size set by this @@ -418,6 +479,35 @@ public class SurfaceTexture { } /** + * This method is invoked from native code only. + * @hide + */ + @SuppressWarnings({"UnusedDeclaration"}) + private static void postOnSetFrameRateEventFromNative(WeakReference<SurfaceTexture> weakSelf, + @FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "postOnSetFrameRateEventFromNative"); + try { + if (Flags.toolkitSetFrameRate()) { + SurfaceTexture st = weakSelf.get(); + if (st != null) { + Handler handler = st.mOnSetFrameRateHandler; + if (handler != null) { + Message msg = new Message(); + msg.obj = new SetFrameRateArgs(frameRate, compatibility, + changeFrameRateStrategy); + handler.sendMessage(msg); + } + } + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + + } + + /** * Returns {@code true} if the SurfaceTexture is single-buffered. * @hide */ |