Extreme battery saver: Allow lowering framerate for experiments.
Bug: 68769804
Test: manual
Change-Id: Ic0c95f32c7ba6d86a997997e480e6d8a5f228f25
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 2ffa1c5..ba6b6cf 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -164,6 +164,7 @@
private long mLastFrameTimeNanos;
private long mFrameIntervalNanos;
private boolean mDebugPrintNextFrameTimeDelta;
+ private int mFPSDivisor = 1;
/**
* Contains information about the current frame for jank-tracking,
@@ -601,6 +602,11 @@
}
}
+ void setFPSDivisor(int divisor) {
+ if (divisor <= 0) divisor = 1;
+ mFPSDivisor = divisor;
+ }
+
void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
@@ -643,6 +649,14 @@
return;
}
+ if (mFPSDivisor > 1) {
+ long timeSinceVsync = frameTimeNanos - mLastFrameTimeNanos;
+ if (timeSinceVsync < (mFrameIntervalNanos * mFPSDivisor) && timeSinceVsync > 0) {
+ scheduleVsyncLocked();
+ return;
+ }
+ }
+
mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
mFrameScheduled = false;
mLastFrameTimeNanos = frameTimeNanos;
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 7c76bab..0a69772 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -190,6 +190,17 @@
public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
"debug.hwui.show_non_rect_clip";
+ /**
+ * Sets the FPS devisor to lower the FPS.
+ *
+ * Sets a positive integer as a divisor. 1 (the default value) menas the full FPS, and 2
+ * means half the full FPS.
+ *
+ *
+ * @hide
+ */
+ public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor";
+
static {
// Try to check OpenGL support early if possible.
isAvailable();
@@ -955,6 +966,9 @@
if (mInitialized) return;
mInitialized = true;
mAppContext = context.getApplicationContext();
+
+ // b/68769804: For low FPS experiments.
+ setFPSDivisor(SystemProperties.getInt(DEBUG_FPS_DIVISOR, 1));
initSched(renderProxy);
initGraphicsStats();
}
@@ -1007,6 +1021,13 @@
observer.mNative = null;
}
+ /** b/68769804: For low FPS experiments. */
+ public static void setFPSDivisor(int divisor) {
+ if (divisor <= 0) divisor = 1;
+ Choreographer.getInstance().setFPSDivisor(divisor);
+ nHackySetRTAnimationsEnabled(divisor == 1);
+ }
+
/** Not actually public - internal use only. This doc to make lint happy */
public static native void disableVsync();
@@ -1075,4 +1096,6 @@
private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
private static native void nSetHighContrastText(boolean enabled);
+ // For temporary experimentation b/66945974
+ private static native void nHackySetRTAnimationsEnabled(boolean enabled);
}
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 519a885..9f3475a 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -937,6 +937,11 @@
Properties::enableHighContrastText = enable;
}
+static void android_view_ThreadedRenderer_hackySetRTAnimationsEnabled(JNIEnv*, jclass,
+ jboolean enable) {
+ Properties::enableRTAnimations = enable;
+}
+
// ----------------------------------------------------------------------------
// FrameMetricsObserver
// ----------------------------------------------------------------------------
@@ -1041,6 +1046,8 @@
(void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode },
{ "disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync },
{ "nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText },
+ { "nHackySetRTAnimationsEnabled", "(Z)V",
+ (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled },
};
static JavaVM* mJvm = nullptr;
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index d41db63..4243e7e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -59,6 +59,7 @@
bool Properties::filterOutTestOverhead = false;
bool Properties::disableVsync = false;
bool Properties::skpCaptureEnabled = false;
+bool Properties::enableRTAnimations = true;
static int property_get_int(const char* key, int defaultValue) {
char buf[PROPERTY_VALUE_MAX] = {
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 9c30e4a..af4b694 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -255,6 +255,9 @@
static bool skpCaptureEnabled;
+ // For experimentation b/68769804
+ ANDROID_API static bool enableRTAnimations;
+
// Used for testing only to change the render pipeline.
static void overrideRenderPipelineType(RenderPipelineType);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b7bb2d15..820789d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -34,6 +34,7 @@
#include "renderstate/Stencil.h"
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
+#include "../Properties.h"
#include <cutils/properties.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -375,6 +376,9 @@
}
if (info.out.hasAnimations || !info.out.canDrawThisFrame) {
+ if (CC_UNLIKELY(!Properties::enableRTAnimations)) {
+ info.out.requiresUiRedraw = true;
+ }
if (!info.out.requiresUiRedraw) {
// If animationsNeedsRedraw is set don't bother posting for an RT anim
// as we will just end up fighting the UI thread.