Loading core/java/android/view/TextureView.java +16 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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()); Loading core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ cc_library_shared_for_libandroid_runtime { static_libs: [ "libnativehelper_lazy", "libziparchive_for_incfs", "libguiflags", ], export_include_dirs: [ Loading core/jni/android_graphics_SurfaceTexture.cpp +93 −58 Original line number Diff line number Diff line Loading @@ -17,27 +17,24 @@ #undef LOG_TAG #define LOG_TAG "SurfaceTexture" #include <stdio.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <com_android_graphics_libgui_flags.h> #include <cutils/atomic.h> #include <gui/BufferQueue.h> #include <gui/Surface.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <stdio.h> #include <surfacetexture/SurfaceTexture.h> #include <surfacetexture/surface_texture_platform.h> #include "core_jni_helpers.h" #include <cutils/atomic.h> #include <utils/Log.h> #include <utils/misc.h> #include "core_jni_helpers.h" #include "jni.h" #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> // ---------------------------------------------------------------------------- Loading @@ -55,6 +52,7 @@ struct fields_t { jfieldID producer; jfieldID frameAvailableListener; jmethodID postEvent; jmethodID postOnSetFrameRateEvent; }; static fields_t fields; Loading Loading @@ -139,31 +137,35 @@ bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) { // ---------------------------------------------------------------------------- class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener { class JNISurfaceTextureContextCommon { public: JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); virtual ~JNISurfaceTextureContext(); virtual void onFrameAvailable(const BufferItem& item); JNISurfaceTextureContextCommon(JNIEnv* env, jobject weakThiz, jclass clazz) : mWeakThiz(env->NewGlobalRef(weakThiz)), mClazz((jclass)env->NewGlobalRef(clazz)) {} private: static JNIEnv* getJNIEnv(); jobject mWeakThiz; jclass mClazz; }; virtual ~JNISurfaceTextureContextCommon() { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->DeleteGlobalRef(mWeakThiz); env->DeleteGlobalRef(mClazz); } else { ALOGW("leaking JNI object references"); } } JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz) : mWeakThiz(env->NewGlobalRef(weakThiz)), mClazz((jclass)env->NewGlobalRef(clazz)) {} void onFrameAvailable(const BufferItem& item) { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); } else { ALOGW("onFrameAvailable event will not posted"); } } JNIEnv* JNISurfaceTextureContext::getJNIEnv() { protected: static JNIEnv* getJNIEnv() { JNIEnv* env = AndroidRuntime::getJNIEnv(); if (env == NULL) { JavaVMAttachArgs args = { JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL }; JavaVMAttachArgs args = {JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL}; JavaVM* vm = AndroidRuntime::getJavaVM(); int result = vm->AttachCurrentThreadAsDaemon(&env, (void*)&args); if (result != JNI_OK) { Loading @@ -174,26 +176,42 @@ JNIEnv* JNISurfaceTextureContext::getJNIEnv() { return env; } JNISurfaceTextureContext::~JNISurfaceTextureContext() { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->DeleteGlobalRef(mWeakThiz); env->DeleteGlobalRef(mClazz); } else { ALOGW("leaking JNI object references"); jobject mWeakThiz; jclass mClazz; }; class JNISurfaceTextureContextFrameAvailableListener : public JNISurfaceTextureContextCommon, public SurfaceTexture::FrameAvailableListener { public: JNISurfaceTextureContextFrameAvailableListener(JNIEnv* env, jobject weakThiz, jclass clazz) : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} void onFrameAvailable(const BufferItem& item) override { JNISurfaceTextureContextCommon::onFrameAvailable(item); } }; class JNISurfaceTextureContextListener : public JNISurfaceTextureContextCommon, public SurfaceTexture::SurfaceTextureListener { public: JNISurfaceTextureContextListener(JNIEnv* env, jobject weakThiz, jclass clazz) : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} void onFrameAvailable(const BufferItem& item) override { JNISurfaceTextureContextCommon::onFrameAvailable(item); } void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */) { void onSetFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy) override { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); env->CallStaticVoidMethod(mClazz, fields.postOnSetFrameRateEvent, mWeakThiz, frameRate, compatibility, changeFrameRateStrategy); } else { ALOGW("onFrameAvailable event will not posted"); ALOGW("onSetFrameRate event will not posted"); } } }; // ---------------------------------------------------------------------------- Loading Loading @@ -229,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, Loading Loading @@ -274,17 +299,27 @@ static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached, return; } sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, clazz)); if (com::android::graphics::libgui::flags::bq_setframerate()) { sp<JNISurfaceTextureContextListener> ctx( new JNISurfaceTextureContextListener(env, weakThiz, clazz)); surfaceTexture->setSurfaceTextureListener(ctx); } else { sp<JNISurfaceTextureContextFrameAvailableListener> ctx( new JNISurfaceTextureContextFrameAvailableListener(env, weakThiz, clazz)); surfaceTexture->setFrameAvailableListener(ctx); SurfaceTexture_setFrameAvailableListener(env, thiz, ctx); } } static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); if (com::android::graphics::libgui::flags::bq_setframerate()) { surfaceTexture->setSurfaceTextureListener(0); } else { surfaceTexture->setFrameAvailableListener(0); SurfaceTexture_setFrameAvailableListener(env, thiz, 0); } SurfaceTexture_setSurfaceTexture(env, thiz, 0); SurfaceTexture_setProducer(env, thiz, 0); } Loading graphics/java/android/graphics/SurfaceTexture.java +90 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.graphics; import android.annotation.FloatRange; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; Loading @@ -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; Loading Loading @@ -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. Loading @@ -99,6 +103,21 @@ public class SurfaceTexture { void onFrameAvailable(SurfaceTexture 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. * Loading Loading @@ -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 Loading Loading @@ -417,6 +478,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 Loading Loading
core/java/android/view/TextureView.java +16 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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()); Loading
core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ cc_library_shared_for_libandroid_runtime { static_libs: [ "libnativehelper_lazy", "libziparchive_for_incfs", "libguiflags", ], export_include_dirs: [ Loading
core/jni/android_graphics_SurfaceTexture.cpp +93 −58 Original line number Diff line number Diff line Loading @@ -17,27 +17,24 @@ #undef LOG_TAG #define LOG_TAG "SurfaceTexture" #include <stdio.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> #include <com_android_graphics_libgui_flags.h> #include <cutils/atomic.h> #include <gui/BufferQueue.h> #include <gui/Surface.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <stdio.h> #include <surfacetexture/SurfaceTexture.h> #include <surfacetexture/surface_texture_platform.h> #include "core_jni_helpers.h" #include <cutils/atomic.h> #include <utils/Log.h> #include <utils/misc.h> #include "core_jni_helpers.h" #include "jni.h" #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> // ---------------------------------------------------------------------------- Loading @@ -55,6 +52,7 @@ struct fields_t { jfieldID producer; jfieldID frameAvailableListener; jmethodID postEvent; jmethodID postOnSetFrameRateEvent; }; static fields_t fields; Loading Loading @@ -139,31 +137,35 @@ bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) { // ---------------------------------------------------------------------------- class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener { class JNISurfaceTextureContextCommon { public: JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); virtual ~JNISurfaceTextureContext(); virtual void onFrameAvailable(const BufferItem& item); JNISurfaceTextureContextCommon(JNIEnv* env, jobject weakThiz, jclass clazz) : mWeakThiz(env->NewGlobalRef(weakThiz)), mClazz((jclass)env->NewGlobalRef(clazz)) {} private: static JNIEnv* getJNIEnv(); jobject mWeakThiz; jclass mClazz; }; virtual ~JNISurfaceTextureContextCommon() { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->DeleteGlobalRef(mWeakThiz); env->DeleteGlobalRef(mClazz); } else { ALOGW("leaking JNI object references"); } } JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz) : mWeakThiz(env->NewGlobalRef(weakThiz)), mClazz((jclass)env->NewGlobalRef(clazz)) {} void onFrameAvailable(const BufferItem& item) { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); } else { ALOGW("onFrameAvailable event will not posted"); } } JNIEnv* JNISurfaceTextureContext::getJNIEnv() { protected: static JNIEnv* getJNIEnv() { JNIEnv* env = AndroidRuntime::getJNIEnv(); if (env == NULL) { JavaVMAttachArgs args = { JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL }; JavaVMAttachArgs args = {JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL}; JavaVM* vm = AndroidRuntime::getJavaVM(); int result = vm->AttachCurrentThreadAsDaemon(&env, (void*)&args); if (result != JNI_OK) { Loading @@ -174,26 +176,42 @@ JNIEnv* JNISurfaceTextureContext::getJNIEnv() { return env; } JNISurfaceTextureContext::~JNISurfaceTextureContext() { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->DeleteGlobalRef(mWeakThiz); env->DeleteGlobalRef(mClazz); } else { ALOGW("leaking JNI object references"); jobject mWeakThiz; jclass mClazz; }; class JNISurfaceTextureContextFrameAvailableListener : public JNISurfaceTextureContextCommon, public SurfaceTexture::FrameAvailableListener { public: JNISurfaceTextureContextFrameAvailableListener(JNIEnv* env, jobject weakThiz, jclass clazz) : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} void onFrameAvailable(const BufferItem& item) override { JNISurfaceTextureContextCommon::onFrameAvailable(item); } }; class JNISurfaceTextureContextListener : public JNISurfaceTextureContextCommon, public SurfaceTexture::SurfaceTextureListener { public: JNISurfaceTextureContextListener(JNIEnv* env, jobject weakThiz, jclass clazz) : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} void onFrameAvailable(const BufferItem& item) override { JNISurfaceTextureContextCommon::onFrameAvailable(item); } void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */) { void onSetFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy) override { JNIEnv* env = getJNIEnv(); if (env != NULL) { env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); env->CallStaticVoidMethod(mClazz, fields.postOnSetFrameRateEvent, mWeakThiz, frameRate, compatibility, changeFrameRateStrategy); } else { ALOGW("onFrameAvailable event will not posted"); ALOGW("onSetFrameRate event will not posted"); } } }; // ---------------------------------------------------------------------------- Loading Loading @@ -229,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, Loading Loading @@ -274,17 +299,27 @@ static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached, return; } sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, clazz)); if (com::android::graphics::libgui::flags::bq_setframerate()) { sp<JNISurfaceTextureContextListener> ctx( new JNISurfaceTextureContextListener(env, weakThiz, clazz)); surfaceTexture->setSurfaceTextureListener(ctx); } else { sp<JNISurfaceTextureContextFrameAvailableListener> ctx( new JNISurfaceTextureContextFrameAvailableListener(env, weakThiz, clazz)); surfaceTexture->setFrameAvailableListener(ctx); SurfaceTexture_setFrameAvailableListener(env, thiz, ctx); } } static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); if (com::android::graphics::libgui::flags::bq_setframerate()) { surfaceTexture->setSurfaceTextureListener(0); } else { surfaceTexture->setFrameAvailableListener(0); SurfaceTexture_setFrameAvailableListener(env, thiz, 0); } SurfaceTexture_setSurfaceTexture(env, thiz, 0); SurfaceTexture_setProducer(env, thiz, 0); } Loading
graphics/java/android/graphics/SurfaceTexture.java +90 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.graphics; import android.annotation.FloatRange; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; Loading @@ -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; Loading Loading @@ -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. Loading @@ -99,6 +103,21 @@ public class SurfaceTexture { void onFrameAvailable(SurfaceTexture 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. * Loading Loading @@ -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 Loading Loading @@ -417,6 +478,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 Loading