diff options
author | Alec Mouri <alecmouri@google.com> | 2020-05-10 05:17:32 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-05-10 05:17:32 +0000 |
commit | 151365a4614a5e5637f494da9cfed27d3a0e13bd (patch) | |
tree | dc7ac71bd1b4d901f99aa00d9b234a2ffbb9e542 | |
parent | 1be04e0cac2301513969674ad8243012f8a0f3d1 (diff) | |
parent | 00f681a5827512248c79180a5fdb364f6140a660 (diff) |
Merge "Dispatch refresh rate callbacks from DMS" into rvc-dev am: 00f681a582
Change-Id: I193dfe7532893c3675d074aa00078ab0885095c3
-rw-r--r-- | core/java/android/hardware/display/DisplayManagerGlobal.java | 85 | ||||
-rw-r--r-- | core/jni/Android.bp | 1 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 32 | ||||
-rw-r--r-- | core/jni/android_hardware_display_DisplayManagerGlobal.cpp | 55 | ||||
-rw-r--r-- | core/jni/include/android_runtime/AndroidRuntime.h | 11 | ||||
-rw-r--r-- | native/android/Android.bp | 7 | ||||
-rw-r--r-- | native/android/choreographer.cpp | 52 | ||||
-rw-r--r-- | native/android/surface_texture.cpp | 52 |
8 files changed, 253 insertions, 42 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 4d645e6052a7..0f9c7088a1d0 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -34,7 +34,6 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; -import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.util.SparseArray; @@ -74,6 +73,8 @@ public final class DisplayManagerGlobal { @UnsupportedAppUsage private static DisplayManagerGlobal sInstance; + // Guarded by mLock + private boolean mDispatchNativeCallbacks = false; private final Object mLock = new Object(); @UnsupportedAppUsage @@ -143,27 +144,35 @@ public final class DisplayManagerGlobal { @UnsupportedAppUsage public DisplayInfo getDisplayInfo(int displayId) { synchronized (mLock) { - DisplayInfo info = null; - if (mDisplayCache != null) { - info = mDisplayCache.query(displayId); - } else { - try { - info = mDm.getDisplayInfo(displayId); - } catch (RemoteException ex) { - ex.rethrowFromSystemServer(); - } - } - if (info == null) { - return null; + return getDisplayInfoLocked(displayId); + } + } + + /** + * Gets information about a particular logical display + * See {@link getDisplayInfo}, but assumes that {@link mLock} is held + */ + private @Nullable DisplayInfo getDisplayInfoLocked(int displayId) { + DisplayInfo info = null; + if (mDisplayCache != null) { + info = mDisplayCache.query(displayId); + } else { + try { + info = mDm.getDisplayInfo(displayId); + } catch (RemoteException ex) { + ex.rethrowFromSystemServer(); } + } + if (info == null) { + return null; + } - registerCallbackIfNeededLocked(); + registerCallbackIfNeededLocked(); - if (DEBUG) { - Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info); - } - return info; + if (DEBUG) { + Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info); } + return info; } /** @@ -341,6 +350,20 @@ public final class DisplayManagerGlobal { for (int i = 0; i < numListeners; i++) { mDisplayListeners.get(i).sendDisplayEvent(displayId, event); } + if (event == EVENT_DISPLAY_CHANGED && mDispatchNativeCallbacks) { + // Choreographer only supports a single display, so only dispatch refresh rate + // changes for the default display. + if (displayId == Display.DEFAULT_DISPLAY) { + // We can likely save a binder hop if we attach the refresh rate onto the + // listener. + DisplayInfo display = getDisplayInfoLocked(displayId); + if (display != null) { + float refreshRate = display.getMode().getRefreshRate(); + // Signal native callbacks if we ever set a refresh rate. + nSignalNativeCallbacks(refreshRate); + } + } + } } } @@ -800,4 +823,30 @@ public final class DisplayManagerGlobal { public void disableLocalDisplayInfoCaches() { mDisplayCache = null; } + + private static native void nSignalNativeCallbacks(float refreshRate); + + // Called from AChoreographer via JNI. + // Registers AChoreographer so that refresh rate callbacks can be dispatched from DMS. + private void registerNativeChoreographerForRefreshRateCallbacks() { + synchronized (mLock) { + registerCallbackIfNeededLocked(); + mDispatchNativeCallbacks = true; + DisplayInfo display = getDisplayInfoLocked(Display.DEFAULT_DISPLAY); + if (display != null) { + // We need to tell AChoreographer instances the current refresh rate so that apps + // can get it for free once a callback first registers. + float refreshRate = display.getMode().getRefreshRate(); + nSignalNativeCallbacks(refreshRate); + } + } + } + + // Called from AChoreographer via JNI. + // Unregisters AChoreographer from receiving refresh rate callbacks. + private void unregisterNativeChoreographerForRefreshRateCallbacks() { + synchronized (mLock) { + mDispatchNativeCallbacks = false; + } + } } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 98f99f786f91..2bd9d3422da8 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -158,6 +158,7 @@ cc_library_shared { "android_hardware_camera2_legacy_LegacyCameraDevice.cpp", "android_hardware_camera2_legacy_PerfMeasurement.cpp", "android_hardware_camera2_DngCreator.cpp", + "android_hardware_display_DisplayManagerGlobal.cpp", "android_hardware_display_DisplayViewport.cpp", "android_hardware_HardwareBuffer.cpp", "android_hardware_SensorManager.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 6fcaddf34322..a420ba67868f 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -18,39 +18,37 @@ #define LOG_TAG "AndroidRuntime" #define LOG_NDEBUG 1 -#include <android_runtime/AndroidRuntime.h> - #include <android-base/macros.h> #include <android-base/properties.h> #include <android/graphics/jni_runtime.h> +#include <android_runtime/AndroidRuntime.h> +#include <assert.h> #include <binder/IBinder.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> -#include <utils/Log.h> -#include <utils/misc.h> -#include <utils/Trace.h> #include <binder/Parcel.h> -#include <utils/threads.h> +#include <bionic/malloc.h> #include <cutils/properties.h> -#include <server_configurable_flags/get_flags.h> - -#include "jni.h" +#include <dirent.h> +#include <dlfcn.h> #include <nativehelper/JNIHelp.h> #include <nativehelper/JniInvocation.h> -#include "android_util_Binder.h" - -#include <stdio.h> +#include <server_configurable_flags/get_flags.h> #include <signal.h> +#include <stdio.h> #include <sys/stat.h> #include <sys/types.h> -#include <signal.h> -#include <dirent.h> -#include <assert.h> -#include <bionic/malloc.h> +#include <utils/Log.h> +#include <utils/Trace.h> +#include <utils/misc.h> +#include <utils/threads.h> #include <string> #include <vector> +#include "android_util_Binder.h" +#include "jni.h" + using namespace android; using android::base::GetProperty; @@ -78,6 +76,7 @@ extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env); extern int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv *env); extern int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv *env); extern int register_android_hardware_camera2_DngCreator(JNIEnv *env); +extern int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env); extern int register_android_hardware_HardwareBuffer(JNIEnv *env); extern int register_android_hardware_SensorManager(JNIEnv *env); extern int register_android_hardware_SerialPort(JNIEnv *env); @@ -1519,6 +1518,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice), REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement), REG_JNI(register_android_hardware_camera2_DngCreator), + REG_JNI(register_android_hardware_display_DisplayManagerGlobal), REG_JNI(register_android_hardware_HardwareBuffer), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_SerialPort), diff --git a/core/jni/android_hardware_display_DisplayManagerGlobal.cpp b/core/jni/android_hardware_display_DisplayManagerGlobal.cpp new file mode 100644 index 000000000000..9f316714a55c --- /dev/null +++ b/core/jni/android_hardware_display_DisplayManagerGlobal.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2020 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. + */ + +#define LOG_TAG "DisplayManagerGlobal-JNI" + +#include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedUtfChars.h> +#include <private/android/choreographer.h> + +#include <vector> + +#include "core_jni_helpers.h" + +using namespace android; + +namespace android { + +// Dispatches the current refresh rate for the default display to all +// choreographer instances +void android_hardware_display_DisplayManagerGlobal_signalNativeCallbacks(JNIEnv* env, jobject, + jfloat refreshRate) { + const constexpr int64_t kNanosPerSecond = 1000 * 1000 * 1000; + const nsecs_t vsyncPeriod = kNanosPerSecond / refreshRate; + + AChoreographer_signalRefreshRateCallbacks(vsyncPeriod); +} + +} // namespace android + +// ---------------------------------------------------------------------------- + +const char* const kClassPathName = "android/hardware/display/DisplayManagerGlobal"; + +static const JNINativeMethod gMethods[] = { + {"nSignalNativeCallbacks", "(F)V", + (void*)android_hardware_display_DisplayManagerGlobal_signalNativeCallbacks}, +}; + +int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env) { + AChoreographer_initJVM(env); + return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); +} diff --git a/core/jni/include/android_runtime/AndroidRuntime.h b/core/jni/include/android_runtime/AndroidRuntime.h index 235127266926..d86d9340e667 100644 --- a/core/jni/include/android_runtime/AndroidRuntime.h +++ b/core/jni/include/android_runtime/AndroidRuntime.h @@ -19,15 +19,14 @@ #ifndef _RUNTIME_ANDROID_RUNTIME_H #define _RUNTIME_ANDROID_RUNTIME_H -#include <utils/Errors.h> #include <binder/IBinder.h> -#include <utils/String8.h> +#include <jni.h> +#include <pthread.h> +#include <utils/Errors.h> #include <utils/String16.h> +#include <utils/String8.h> #include <utils/Vector.h> #include <utils/threads.h> -#include <pthread.h> -#include <jni.h> - namespace android { @@ -154,6 +153,6 @@ private: static int javaThreadShell(void* args); }; -} +} // namespace android #endif diff --git a/native/android/Android.bp b/native/android/Android.bp index ccc89f01955b..b894dc15d56c 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -37,6 +37,7 @@ cc_library_shared { srcs: [ "asset_manager.cpp", + "choreographer.cpp", "configuration.cpp", "hardware_buffer_jni.cpp", "input.cpp", @@ -49,6 +50,7 @@ cc_library_shared { "sharedmem.cpp", "storage_manager.cpp", "surface_control.cpp", + "surface_texture.cpp", "system_fonts.cpp", "trace.cpp", "thermal.cpp" @@ -76,6 +78,7 @@ cc_library_shared { "libpowermanager", "android.hardware.configstore@1.0", "android.hardware.configstore-utils", + "libnativedisplay", ], static_libs: [ @@ -83,9 +86,9 @@ cc_library_shared { "libarect", ], - header_libs: [ "libhwui_internal_headers" ], + header_libs: [ "libhwui_internal_headers",], - whole_static_libs: ["libnativedisplay", "libnativewindow"], + whole_static_libs: ["libnativewindow"], export_static_lib_headers: ["libarect"], diff --git a/native/android/choreographer.cpp b/native/android/choreographer.cpp new file mode 100644 index 000000000000..38641de0efb3 --- /dev/null +++ b/native/android/choreographer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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. + */ + +#include <private/android/choreographer.h> + +using namespace android; + +AChoreographer* AChoreographer_getInstance() { + return AChoreographer_routeGetInstance(); +} +void AChoreographer_postFrameCallback(AChoreographer* choreographer, + AChoreographer_frameCallback callback, void* data) { + return AChoreographer_routePostFrameCallback(choreographer, callback, data); +} +void AChoreographer_postFrameCallbackDelayed(AChoreographer* choreographer, + AChoreographer_frameCallback callback, void* data, + long delayMillis) { + return AChoreographer_routePostFrameCallbackDelayed(choreographer, callback, data, delayMillis); +} +void AChoreographer_postFrameCallback64(AChoreographer* choreographer, + AChoreographer_frameCallback64 callback, void* data) { + return AChoreographer_routePostFrameCallback64(choreographer, callback, data); +} +void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer, + AChoreographer_frameCallback64 callback, void* data, + uint32_t delayMillis) { + return AChoreographer_routePostFrameCallbackDelayed64(choreographer, callback, data, + delayMillis); +} +void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer, + AChoreographer_refreshRateCallback callback, + void* data) { + return AChoreographer_routeRegisterRefreshRateCallback(choreographer, callback, data); +} +void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer, + AChoreographer_refreshRateCallback callback, + void* data) { + return AChoreographer_routeUnregisterRefreshRateCallback(choreographer, callback, data); +} diff --git a/native/android/surface_texture.cpp b/native/android/surface_texture.cpp new file mode 100644 index 000000000000..ff35204b2ec9 --- /dev/null +++ b/native/android/surface_texture.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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. + */ + +#include <android/surface_texture_jni.h> +#include <surfacetexture/surface_texture_platform.h> + +using namespace android; + +ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st) { + return ASurfaceTexture_routeAcquireANativeWindow(st); +} + +int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t texName) { + return ASurfaceTexture_routeAttachToGLContext(st, texName); +} + +int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st) { + return ASurfaceTexture_routeDetachFromGLContext(st); +} + +void ASurfaceTexture_release(ASurfaceTexture* st) { + return ASurfaceTexture_routeRelease(st); +} + +int ASurfaceTexture_updateTexImage(ASurfaceTexture* st) { + return ASurfaceTexture_routeUpdateTexImage(st); +} + +void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]) { + return ASurfaceTexture_routeGetTransformMatrix(st, mtx); +} + +int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st) { + return ASurfaceTexture_routeGetTimestamp(st); +} + +ASurfaceTexture* ASurfaceTexture_fromSurfaceTexture(JNIEnv* env, jobject surfacetexture) { + return ASurfaceTexture_routeFromSurfaceTexture(env, surfacetexture); +} |