Implement game mode framerate override
Add logic for setting throttling framerate requested
by Game Dashboard interventions.
- Refactored of FrameRateOverrideMappings in Scheduler
- Have mSupportsFrameRateOverride only guard mFrameRateOverrideByContent
- Remove logic that disables framerate override when it's not a divider
Bug: b/204322816
Test: atest FrameRateOverrideHostTest
Change-Id: I1a2caf378cd87ce4830f6fc48332b5df518330cc
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0227043..b7594df 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -1346,6 +1346,21 @@
SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener));
return remote()->transact(BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, data, &reply);
}
+
+ status_t setOverrideFrameRate(uid_t uid, float frameRate) override {
+ Parcel data, reply;
+ SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+ SAFE_PARCEL(data.writeUint32, uid);
+ SAFE_PARCEL(data.writeFloat, frameRate);
+
+ status_t err = remote()->transact(BnSurfaceComposer::SET_OVERRIDE_FRAME_RATE, data, &reply);
+ if (err != NO_ERROR) {
+ ALOGE("setOverrideFrameRate: failed to transact %s (%d)", strerror(-err), err);
+ return err;
+ }
+
+ return NO_ERROR;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -2306,6 +2321,17 @@
return removeWindowInfosListener(listener);
}
+ case SET_OVERRIDE_FRAME_RATE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+
+ uid_t uid;
+ SAFE_PARCEL(data.readUint32, &uid);
+
+ float frameRate;
+ SAFE_PARCEL(data.readFloat, &frameRate);
+
+ return setOverrideFrameRate(uid, frameRate);
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index b4f6cd5..31456cd 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2094,6 +2094,10 @@
displayModeId);
}
+status_t SurfaceComposerClient::setOverrideFrameRate(uid_t uid, float frameRate) {
+ return ComposerService::getComposerService()->setOverrideFrameRate(uid, frameRate);
+}
+
void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
ComposerService::getComposerService()->setAutoLowLatencyMode(display, on);
}
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index f37580c..fb4fb7e 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -559,6 +559,13 @@
int8_t compatibility, int8_t changeFrameRateStrategy) = 0;
/*
+ * Set the override frame rate for a specified uid by GameManagerService.
+ * Passing the frame rate and uid to SurfaceFlinger to update the override mapping
+ * in the scheduler.
+ */
+ virtual status_t setOverrideFrameRate(uid_t uid, float frameRate) = 0;
+
+ /*
* Sets the frame timeline vsync info received from choreographer that corresponds to next
* buffer submitted on that surface.
*/
@@ -678,6 +685,7 @@
SET_BOOT_DISPLAY_MODE,
CLEAR_BOOT_DISPLAY_MODE,
GET_PREFERRED_BOOT_DISPLAY_MODE,
+ SET_OVERRIDE_FRAME_RATE,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index c192323..4f92878 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -25,6 +25,7 @@
#include <binder/IBinder.h>
+#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
#include <utils/SortedVector.h>
@@ -175,6 +176,9 @@
static status_t clearBootDisplayMode(const sp<IBinder>& display);
// Gets the display mode in which the device boots if there is no user-preferred display mode
static status_t getPreferredBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId*);
+ // Sets the frame rate of a particular app (uid). This is currently called
+ // by GameManager.
+ static status_t setOverrideFrameRate(uid_t uid, float frameRate);
// Switches on/off Auto Low Latency Mode on the connected display. This should only be
// called if the connected display supports Auto Low Latency Mode as reported by
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 999874b..0ebd11c 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -31,9 +31,11 @@
#include <gui/SyncScreenCaptureListener.h>
#include <inttypes.h>
#include <private/gui/ComposerService.h>
+#include <sys/types.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
#include <ui/Rect.h>
+#include <utils/Errors.h>
#include <utils/String8.h>
#include <limits>
@@ -925,6 +927,8 @@
return NO_ERROR;
}
+ status_t setOverrideFrameRate(uid_t /*uid*/, float /*frameRate*/) override { return NO_ERROR; }
+
protected:
IBinder* onAsBinder() override { return nullptr; }