summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2023-11-09 07:28:13 -0800
committerLinux Build Service Account <lnxbuild@localhost>2023-11-09 07:28:13 -0800
commit8a36004d01ec29226b19786cd4ee711ae8a34ce2 (patch)
tree9e0b1a3949b81469ac5cd541972acffd6f354164
parente9d3775d851ab7a23bb16fd9ab6106a47285139e (diff)
parent08aa096b3b4f455803b0f3b098966494b8ef3a3f (diff)
Merge 08aa096b3b4f455803b0f3b098966494b8ef3a3f on remote branch
Change-Id: Ia29c14824179c52df57a5018eb0776c3827e1edb
-rw-r--r--libs/gui/Android.bp12
-rw-r--r--libs/gui/QtiExtension/QtiSurfaceExtension.cpp138
-rw-r--r--libs/gui/QtiExtension/QtiSurfaceExtension.h33
-rw-r--r--libs/gui/Surface.cpp13
-rw-r--r--libs/gui/include/gui/Surface.h15
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp45
-rw-r--r--services/surfaceflinger/DisplayDevice.h4
-rw-r--r--services/surfaceflinger/QtiExtension/QtiNullExtension.cpp5
-rw-r--r--services/surfaceflinger/QtiExtension/QtiNullExtension.h2
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp53
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h5
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h2
-rw-r--r--services/surfaceflinger/Scheduler/LayerHistory.cpp9
-rw-r--r--services/surfaceflinger/Scheduler/LayerHistory.h4
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp4
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp16
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
18 files changed, 355 insertions, 7 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 20261f2ea4..0533aadbbe 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -452,6 +452,7 @@ qtidisplayextension_cc_library_static {
vendor_available: true,
defaults: [
"libgui_bufferqueue-defaults",
+ "libguiextension_defaults",
],
header_libs: [
"libgui_aidl_headers",
@@ -471,6 +472,7 @@ qtidisplayextension_cc_library_static {
},
srcs: [
"QtiExtension/QtiBLASTBufferQueueExtension.cpp",
+ "QtiExtension/QtiSurfaceExtension.cpp",
],
local_include_dirs: ["QtiExtension"],
export_include_dirs: ["QtiExtension"],
@@ -484,7 +486,15 @@ qtidisplayextension_cc_defaults {
"-DQTI_DISPLAY_EXTENSION",
],
}
- }
+ },
+ header_libs: [
+ "display_intf_headers",
+ ],
+ shared_libs: [
+ "libgralloctypes",
+ "libhidlbase",
+ "android.hardware.graphics.mapper@4.0",
+ ],
}
cc_defaults {
diff --git a/libs/gui/QtiExtension/QtiSurfaceExtension.cpp b/libs/gui/QtiExtension/QtiSurfaceExtension.cpp
new file mode 100644
index 0000000000..4e5a955096
--- /dev/null
+++ b/libs/gui/QtiExtension/QtiSurfaceExtension.cpp
@@ -0,0 +1,138 @@
+/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+// #define LOG_NDEBUG 0
+
+#include <cutils/properties.h>
+#include <regex>
+#include <binder/IServiceManager.h>
+#include <log/log.h>
+#include <gralloctypes/Gralloc4.h>
+#include <hidl/HidlSupport.h>
+
+#include "QtiGralloc.h"
+#include "QtiSurfaceExtension.h"
+
+using android::hardware::graphics::mapper::V4_0::IMapper;
+using android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::hidl_vec;
+using qtigralloc::MetadataType_BufferDequeueDuration;
+
+namespace android::libguiextension {
+
+QtiSurfaceExtension::QtiSurfaceExtension(Surface* surface)
+ : mQtiSurface(surface) {
+ if (!mQtiSurface) {
+ ALOGW("Invalid pointer to Surface passed");
+ } else {
+ mMapper = IMapper::getService();
+ if (mMapper == nullptr) {
+ ALOGI("mapper 4.x is not supported");
+ } else if (mMapper->isRemote()) {
+ LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
+ }
+
+ char value[PROPERTY_VALUE_MAX];
+ int int_value = 0;
+
+ property_get("vendor.display.enable_optimal_refresh_rate", value, "0");
+ int_value = atoi(value);
+ enable_optimal_refresh_rate_ = (int_value == 1) ? true : false;
+ ALOGV("Successfully created QtiSurfaceExtension");
+ }
+}
+
+void QtiSurfaceExtension::qtiSetBufferDequeueDuration(std::string layerName,
+ android_native_buffer_t* buffer,
+ nsecs_t dequeue_duration) {
+ if (!mMapper) {
+ return;
+ }
+
+ if (!buffer) {
+ ALOGW("Pointer to android_native_buffer_t is invalid");
+ return;
+ }
+
+ if (!enable_optimal_refresh_rate_ || !isGame(layerName)) {
+ return;
+ }
+
+ hidl_vec<uint8_t> encodedMetadata;
+ const status_t status =
+ gralloc4::encodeInt64(MetadataType_BufferDequeueDuration,
+ dequeue_duration, &encodedMetadata);
+ if (status != OK) {
+ ALOGE("Encoding metadata(%s) failed with %d",
+ MetadataType_BufferDequeueDuration.name.c_str(), status);
+ return;
+ }
+
+ auto ret =
+ mMapper->set(const_cast<native_handle_t*>(buffer->handle),
+ MetadataType_BufferDequeueDuration, encodedMetadata);
+ const Error error = ret.withDefault(Error::NO_RESOURCES);
+ switch (error) {
+ case Error::BAD_DESCRIPTOR:
+ case Error::BAD_BUFFER:
+ case Error::BAD_VALUE:
+ case Error::NO_RESOURCES:
+ ALOGE("set(%s, %" PRIu64 ", ...) failed with %d",
+ MetadataType_BufferDequeueDuration.name.c_str(),
+ MetadataType_BufferDequeueDuration.value, error);
+ break;
+ // It is not an error to attempt to set metadata that a particular gralloc implementation
+ // happens to not support.
+ case Error::UNSUPPORTED:
+ case Error::NONE:
+ break;
+ }
+}
+
+bool QtiSurfaceExtension::isGame(std::string layerName) {
+ if (layerName == mQtiLayerName) {
+ return mQtiIsGame;
+ }
+
+ mQtiLayerName = layerName;
+ mQtiIsGame = false;
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> perfservice = sm->checkService(String16("vendor.perfservice"));
+ if (perfservice == nullptr) {
+ ALOGE("Cannot find perfservice");
+ return false;
+ }
+ String16 ifName = perfservice->getInterfaceDescriptor();
+ if (ifName.size() > 0) {
+ const std::regex re("(?:SurfaceView\\[)([^/]+).*");
+ std::smatch match;
+ if (!std::regex_match(layerName, match, re)) {
+ return false;
+ }
+ String16 pkgName = String16(match[1].str().c_str());
+
+ Parcel data, reply;
+ int GAME_TYPE = 2;
+ int VENDOR_FEEDBACK_WORKLOAD_TYPE = 0x00001601;
+ int PERF_GET_FEEDBACK = IBinder::FIRST_CALL_TRANSACTION + 7;
+ int array[0];
+ data.markForBinder(perfservice);
+ data.writeInterfaceToken(ifName);
+ data.writeInt32(VENDOR_FEEDBACK_WORKLOAD_TYPE);
+ data.writeString16(pkgName);
+ data.writeInt32(getpid());
+ data.writeInt32Array(0, array);
+ perfservice->transact(PERF_GET_FEEDBACK, data, &reply);
+ reply.readExceptionCode();
+ int type = reply.readInt32();
+ if (type == GAME_TYPE) {
+ mQtiIsGame = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+} // namespace android::libguiextension
diff --git a/libs/gui/QtiExtension/QtiSurfaceExtension.h b/libs/gui/QtiExtension/QtiSurfaceExtension.h
new file mode 100644
index 0000000000..7a2269dba0
--- /dev/null
+++ b/libs/gui/QtiExtension/QtiSurfaceExtension.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+#pragma once
+
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+
+#include "../include/gui/Surface.h"
+
+namespace android {
+
+namespace libguiextension {
+
+class QtiSurfaceExtension {
+public:
+ QtiSurfaceExtension(Surface* surface);
+ ~QtiSurfaceExtension() = default;
+
+ void qtiSetBufferDequeueDuration(std::string layerName, android_native_buffer_t* buffer,
+ nsecs_t dequeue_duration);
+
+private:
+ bool isGame(std::string layerName);
+
+ Surface* mQtiSurface = nullptr;
+ bool mQtiIsGame = false;
+ std::string mQtiLayerName = "";
+ sp<android::hardware::graphics::mapper::V4_0::IMapper> mMapper = nullptr;
+ bool enable_optimal_refresh_rate_ = false;
+};
+
+} // namespace libguiextension
+} // namespace android
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index ed691006e9..661366ca92 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -124,6 +124,12 @@ Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controll
mSwapIntervalZero = false;
mMaxBufferCount = NUM_BUFFER_SLOTS;
mSurfaceControlHandle = surfaceControlHandle;
+
+ /* QTI_BEGIN */
+ if (!mQtiSurfaceExtn) {
+ mQtiSurfaceExtn = new libguiextension::QtiSurfaceExtension(this);
+ }
+ /* QTI_END */
}
Surface::~Surface() {
@@ -1035,6 +1041,13 @@ void Surface::applyGrallocMetadataLocked(
android_native_buffer_t* buffer,
const IGraphicBufferProducer::QueueBufferInput& queueBufferInput) {
ATRACE_CALL();
+
+ /* QTI_BEGIN */
+ if (mQtiSurfaceExtn) {
+ mQtiSurfaceExtn->qtiSetBufferDequeueDuration(getDebugName(), buffer, mLastDequeueDuration);
+ }
+ /* QTI_END */
+
auto& mapper = GraphicBufferMapper::get();
mapper.setDataspace(buffer->handle, static_cast<ui::Dataspace>(queueBufferInput.dataSpace));
if (mHdrMetadataIsSet & HdrMetadata::SMPTE2086)
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 39a59e42aa..6b64b2ad0c 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -33,8 +33,18 @@
#include <shared_mutex>
#include <unordered_set>
+/* QTI_BEGIN */
+#include "../../QtiExtension/QtiSurfaceExtension.h"
+/* QTI_END */
+
namespace android {
+/* QTI_BEGIN */
+namespace libguiextension {
+class QtiSurfaceExtension;
+};
+/* QTI_END */
+
namespace gui {
class ISurfaceComposer;
} // namespace gui
@@ -228,6 +238,11 @@ private:
Surface& operator = (const Surface& rhs);
Surface(const Surface& rhs);
+ /* QTI_BEGIN */
+ friend class libguiextension::QtiSurfaceExtension;
+ libguiextension::QtiSurfaceExtension* mQtiSurfaceExtn = nullptr;
+ /* QTI_END */
+
// ANativeWindow hooks
static int hook_cancelBuffer(ANativeWindow* window,
ANativeWindowBuffer* buffer, int fenceFd);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index f0b6763cd5..1e7417165e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -45,6 +45,10 @@
#include <system/window.h>
#include <ui/GraphicTypes.h>
+/* QTI_BEGIN */
+#include <cutils/properties.h>
+/* QTI_END */
+
#include "Display/DisplaySnapshot.h"
#include "DisplayDevice.h"
#include "FrontEnd/DisplayInfo.h"
@@ -117,6 +121,12 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
// initialize the display orientation transform.
setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
+
+ /* QTI_BEGIN */
+ char value[PROPERTY_VALUE_MAX];
+ property_get("vendor.display.enable_fb_scaling", value, "0");
+ mUseFbScaling = atoi(value);
+ /* QTI_END */
}
DisplayDevice::~DisplayDevice() = default;
@@ -160,14 +170,44 @@ auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo {
inversePhysicalOrientation),
width, height);
const auto& displayTransform = undoPhysicalOrientation * getTransform();
+
+ /* QTI_BEGIN */
+ auto currMode = refreshRateSelector().getActiveMode();
+ ui::Transform scale;
+ ui::Transform rotationTransform = getTransform();
+ rotationTransform.set(getTransform().getOrientation(), currMode.modePtr->getWidth(),
+ currMode.modePtr->getHeight());
+ scale.set(1, 0, 0, 1);
+ if(mUseFbScaling && isPrimary()){ //use fb_scaling
+ const float scaleX = static_cast<float>(currMode.modePtr->getWidth()) / getWidth();
+ const float scaleY = static_cast<float>(currMode.modePtr->getHeight()) / getHeight();
+ scale.set(scaleX, 0, 0, scaleY);
+ }
+ const auto& displayTransform_s = undoPhysicalOrientation * rotationTransform * scale;
+ /* QTI_END */
+
// Send the inverse display transform to input so it can convert display coordinates to
// logical display.
- info.transform = displayTransform.inverse();
info.logicalWidth = getLayerStackSpaceRect().width();
info.logicalHeight = getLayerStackSpaceRect().height();
- return {.info = info,
+ /* QTI_BEGIN */
+ if (mUseFbScaling && isPrimary()) {
+ info.transform = displayTransform_s.inverse();
+ return {.info = info,
+ .transform = displayTransform_s,
+ .receivesInput = receivesInput(),
+ .isSecure = isSecure(),
+ .isPrimary = isPrimary(),
+ .isVirtual = isVirtual(),
+ .rotationFlags = ui::Transform::toRotationFlags(mOrientation),
+ .transformHint = getTransformHint()};
+ }
+ /* QTI_END */
+ else {
+ info.transform = displayTransform.inverse();
+ return {.info = info,
.transform = displayTransform,
.receivesInput = receivesInput(),
.isSecure = isSecure(),
@@ -175,6 +215,7 @@ auto DisplayDevice::getFrontEndInfo() const -> frontend::DisplayInfo {
.isVirtual = isVirtual(),
.rotationFlags = ui::Transform::toRotationFlags(mOrientation),
.transformHint = getTransformHint()};
+ }
}
void DisplayDevice::setPowerMode(hal::PowerMode mode) {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e31dfd86f0..538921ba9d 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -284,6 +284,10 @@ private:
const wp<IBinder> mDisplayToken;
const int32_t mSequenceId;
+ /* QTI_BEGIN */
+ bool mUseFbScaling = false;
+ /* QTI_END */
+
const std::shared_ptr<compositionengine::Display> mCompositionDisplay;
std::string mDisplayName;
diff --git a/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp b/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
index 9e158dee63..6ac1ca3bf9 100644
--- a/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
+++ b/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
@@ -55,6 +55,8 @@ bool QtiNullExtension::qtiLatchMediaContent(sp<Layer> layer) {
}
void QtiNullExtension::qtiUpdateBufferData(bool qtiLatchMediaContent, const layer_state_t& s) {}
+void QtiNullExtension::qtiOnComposerHalRefresh() {}
+
/*
* Methods that call the FeatureManager APIs.
*/
@@ -168,6 +170,9 @@ uint32_t QtiNullExtension::qtiGetLayerClass(std::string mName) {
}
void QtiNullExtension::qtiSetVisibleLayerInfo(DisplayId displayId,
const char* name, int32_t sequence) {}
+bool QtiNullExtension::qtiIsSmomoOptimalRefreshActive() {
+ return false;
+}
/*
* Methods for speculative fence
diff --git a/services/surfaceflinger/QtiExtension/QtiNullExtension.h b/services/surfaceflinger/QtiExtension/QtiNullExtension.h
index f961d95d44..c334458356 100644
--- a/services/surfaceflinger/QtiExtension/QtiNullExtension.h
+++ b/services/surfaceflinger/QtiExtension/QtiNullExtension.h
@@ -39,6 +39,7 @@ public:
composer::DisplayExtnIntf* qtiGetDisplayExtn() { return nullptr; }
bool qtiLatchMediaContent(sp<Layer> layer) override;
void qtiUpdateBufferData(bool qtiLatchMediaContent, const layer_state_t& s) override;
+ void qtiOnComposerHalRefresh() override;
/*
* Methods that call the FeatureManager APIs.
@@ -118,6 +119,7 @@ public:
uint32_t qtiGetLayerClass(std::string mName) override;
void qtiSetVisibleLayerInfo(DisplayId displayId,
const char* name, int32_t sequence) override;
+ bool qtiIsSmomoOptimalRefreshActive() override;
/*
* Methods for speculative fence
diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
index be4f21b0a9..52b5c51eb7 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
@@ -190,7 +190,6 @@ QtiSurfaceFlingerExtensionIntf* QtiSurfaceFlingerExtension::qtiPostInit(
qtiUpdateVsyncConfiguration();
mQtiSFExtnBootComplete = true;
-#ifdef FPS_MITIGATION_ENABLED
ConditionalLock lock(mQtiFlinger->mStateLock,
std::this_thread::get_id() != mQtiFlinger->mMainThreadId);
const auto displayDevice = mQtiFlinger->getDefaultDisplayDeviceLocked();
@@ -212,6 +211,11 @@ QtiSurfaceFlingerExtensionIntf* QtiSurfaceFlingerExtension::qtiPostInit(
}
if (mQtiDisplayExtnIntf) {
+ mQtiDisplayExtnIntf->SetSupportedRefreshRates(fps_list);
+ }
+
+#ifdef FPS_MITIGATION_ENABLED
+ if (mQtiDisplayExtnIntf) {
mQtiDisplayExtnIntf->SetFpsMitigationCallback(
[this](float newLevelFps) { qtiSetDesiredModeByThermalLevel(newLevelFps); },
fps_list);
@@ -466,6 +470,10 @@ void QtiSurfaceFlingerExtension::qtiUpdateBufferData(bool qtiLatchMediaContent,
}
}
+void QtiSurfaceFlingerExtension::qtiOnComposerHalRefresh() {
+ mComposerRefreshNotified = true;
+}
+
/*
* Methods that call the FeatureManager APIs.
*/
@@ -548,6 +556,11 @@ void QtiSurfaceFlingerExtension::qtiSendInitialFps(uint32_t fps) {
}
void QtiSurfaceFlingerExtension::qtiNotifyDisplayUpdateImminent() {
+ if(mQtiDisplayExtnIntf && !mComposerRefreshNotified) {
+ mQtiDisplayExtnIntf->NotifyDisplayUpdateImminent();
+ }
+ mComposerRefreshNotified = false;
+
if (!mQtiFeatureManager->qtiIsExtensionFeatureEnabled(QtiFeature::kEarlyWakeUp)) {
mQtiFlinger->mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset();
return;
@@ -1376,10 +1389,15 @@ void QtiSurfaceFlingerExtension::qtiSyncToDisplayHardware() {
}
}
+bool QtiSurfaceFlingerExtension::qtiIsSmomoOptimalRefreshActive() {
+ return mQtiSmomoOptimalRefreshActive;
+}
+
void QtiSurfaceFlingerExtension::qtiUpdateSmomoState() {
ATRACE_NAME("SmoMoUpdateState");
Mutex::Autolock lock(mQtiFlinger->mStateLock);
+ mQtiSmomoOptimalRefreshActive = false;
// Check if smomo instances exist.
if (!mQtiSmomoInstances.size()) {
return;
@@ -1457,6 +1475,23 @@ void QtiSurfaceFlingerExtension::qtiUpdateSmomoState() {
: static_cast<uint32_t>(fps));
}
+ if (numActiveDisplays == 1) {
+ std::map<int, int> refresh_rate_votes;
+ for (auto& instance : mQtiSmomoInstances) {
+ if (!instance.active) {
+ continue;
+ }
+ instance.smoMo->GetRefreshRateVote(refresh_rate_votes);
+ mQtiFlinger->mScheduler->qtiUpdateSmoMoRefreshRateVote(refresh_rate_votes);
+ for (auto it = refresh_rate_votes.begin(); it != refresh_rate_votes.end(); it++) {
+ if (it->second != -1) {
+ mQtiSmomoOptimalRefreshActive = true;
+ break;
+ }
+ }
+ }
+ }
+
// Disable DRC if active displays is more than 1.
for (auto& instance : mQtiSmomoInstances) {
instance.smoMo->SetRefreshRateChangeStatus((numActiveDisplays == 1));
@@ -1540,10 +1575,19 @@ void QtiSurfaceFlingerExtension::qtiUpdateSmomoLayerInfo(
#endif
smoMo->CollectLayerStats(bufferStats);
- const auto& schedule = mQtiFlinger->mScheduler->getVsyncSchedule();
- auto vsyncTime = schedule->getTracker().nextAnticipatedVSyncTimeFrom(SYSTEM_TIME_MONOTONIC);
+ const auto &schedule = mQtiFlinger->mScheduler->getVsyncSchedule();
+ nsecs_t sfOffset = mQtiFlinger->mVsyncConfiguration->getCurrentConfigs().late.sfOffset;
+ const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ auto vsyncTime = schedule->getTracker().nextAnticipatedVSyncTimeFrom(now);
+ nsecs_t sfVsyncTime = vsyncTime + sfOffset;
+ auto vsyncPeriod = schedule->getTracker().currentPeriod();
+ if (now >= sfVsyncTime) {
+ sfVsyncTime += vsyncPeriod;
+ } else if (now <= sfVsyncTime - vsyncPeriod) {
+ sfVsyncTime -= vsyncPeriod;
+ }
- if (smoMo->FrameIsLate(bufferStats.id, vsyncTime)) {
+ if (smoMo->FrameIsLate(bufferStats.id, sfVsyncTime)) {
qtiScheduleCompositeImmed();
}
}
@@ -2027,6 +2071,7 @@ void QtiSurfaceFlingerExtension::qtiSetFrameBufferSizeForScaling(
} else {
mQtiDisplaySizeChanged = true;
}
+ mQtiFlinger->setTransactionFlags(eDisplayTransactionNeeded);
}
}
diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
index ba5880feca..16b2c26289 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
@@ -13,6 +13,7 @@
#include <binder/IBinder.h>
#include <composer_extn_intf.h>
#include <list>
+#include <map>
#include "../DisplayHardware/HWComposer.h"
#include "../DisplayHardware/PowerAdvisor.h"
@@ -139,6 +140,7 @@ public:
composer::DisplayExtnIntf* qtiGetDisplayExtn() { return mQtiDisplayExtnIntf; }
bool qtiLatchMediaContent(sp<Layer> layer) override;
void qtiUpdateBufferData(bool qtiLatchMediaContent, const layer_state_t& s) override;
+ void qtiOnComposerHalRefresh() override;
/*
* Methods that call the FeatureManager APIs.
@@ -220,6 +222,7 @@ public:
uint32_t qtiGetLayerClass(std::string mName) override;
void qtiSetVisibleLayerInfo(DisplayId displayId,
const char* name, int32_t sequence) override;
+ bool qtiIsSmomoOptimalRefreshActive() override;
/*
* Methods for Dolphin APIs
@@ -268,6 +271,7 @@ private:
QtiWorkDurationsExtension* mQtiWorkDurationsExtn = nullptr;
QtiDolphinWrapper* mQtiDolphinWrapper = nullptr;
+ bool mQtiSmomoOptimalRefreshActive = false;
bool mQtiEnabledIDC = false;
bool mQtiInitVsyncConfigurationExtn = false;
bool mQtiInternalPresentationDisplays = false;
@@ -281,6 +285,7 @@ private:
int mQtiRETid = 0;
int mQtiSFTid = 0;
int mQtiUiLayerFrameCount = 180;
+ bool mComposerRefreshNotified = false;
uint32_t mQtiCurrentFps = 0;
float mQtiThermalLevelFps = 0;
float mQtiLastCachedFps = 0;
diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h
index 81275f6fb3..5781672d80 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h
@@ -69,6 +69,7 @@ public:
virtual composer::DisplayExtnIntf* qtiGetDisplayExtn() = 0;
virtual bool qtiLatchMediaContent(sp<Layer> layer) = 0;
virtual void qtiUpdateBufferData(bool qtiLatchMediaContent, const layer_state_t& s) = 0;
+ virtual void qtiOnComposerHalRefresh() = 0;
/*
* Methods that call the FeatureManager APIs.
@@ -150,6 +151,7 @@ public:
virtual uint32_t qtiGetLayerClass(std::string mName) = 0;
virtual void qtiSetVisibleLayerInfo(DisplayId displayId,
const char* name, int32_t sequence) = 0;
+ virtual bool qtiIsSmomoOptimalRefreshActive() = 0;
/*
* Methods for Dolphin APIs
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index ca71a19840..d6a7273599 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -188,6 +188,15 @@ auto LayerHistory::summarize(const RefreshRateSelector& selector, nsecs_t now) -
ATRACE_FORMAT("%s", info->getName().c_str());
auto vote = info->getRefreshRateVote(selector, now);
+
+ /* QTI_BEGIN */
+ if (refresh_rate_votes_.find(key) != refresh_rate_votes_.end() &&
+ refresh_rate_votes_[key] != -1) {
+ vote.fps = Fps::fromValue(refresh_rate_votes_[key]);
+ vote.type = LayerHistory::LayerVoteType::ExplicitExact;
+ }
+ /* QTI_END */
+
// Skip NoVote layer as those don't have any requirements
if (vote.type == LayerVoteType::NoVote) {
continue;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
index 2b59e625b1..aed26ba9a2 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.h
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -89,6 +89,9 @@ public:
/* QTI_BEGIN */
void qtiUpdateThermalFps(float fps) { mQtiThermalFps = fps; }
+ void qtiUpdateSmoMoRefreshRateVote(std::map<int, int>& refresh_rate_votes) {
+ refresh_rate_votes_ = refresh_rate_votes;
+ }
/* QTI_END */
private:
@@ -146,6 +149,7 @@ private:
/* QTI_BEGIN */
// If Thermal mitigation enabled, limit to thermal Fps
float mQtiThermalFps = 0.0f;
+ std::map<int, int> refresh_rate_votes_;
/* QTI_END */
};
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 9651752235..743aed204a 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -966,6 +966,10 @@ void Scheduler::qtiUpdateThermalFps(float fps) {
mQtiThermalFps = fps;
mLayerHistory.qtiUpdateThermalFps(fps);
}
+
+void Scheduler::qtiUpdateSmoMoRefreshRateVote(std::map<int, int>& refresh_rate_votes) {
+ mLayerHistory.qtiUpdateSmoMoRefreshRateVote(refresh_rate_votes);
+}
/* QTI_END */
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ae96b8a79f..6cf0e8ad48 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -307,6 +307,7 @@ public:
/* QTI_BEGIN */
void qtiUpdateThermalFps(float fps);
+ void qtiUpdateSmoMoRefreshRateVote(std::map<int, int>& refresh_rate_votes);
/* QTI_END */
private:
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d4552c2725..8e8bc8a0f1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2155,6 +2155,9 @@ void SurfaceFlinger::onComposerHalSeamlessPossible(hal::HWDisplayId) {
void SurfaceFlinger::onComposerHalRefresh(hal::HWDisplayId) {
Mutex::Autolock lock(mStateLock);
+ /* QTI_BEGIN */
+ mQtiSFExtnIntf->qtiOnComposerHalRefresh();
+ /* QTI_END */
scheduleComposite(FrameHint::kNone);
}
@@ -2426,6 +2429,10 @@ bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expe
const TimePoint lastScheduledPresentTime = mScheduledPresentTime;
/* QTI_BEGIN */
+ std::unique_lock<std::mutex> lck (mSmomoMutex, std::defer_lock);
+ if (mQtiSFExtnIntf->qtiIsSmomoOptimalRefreshActive()) {
+ lck.lock();
+ }
mQtiSFExtnIntf->qtiOnVsync(expectedVsyncTime.ns());
/* QTI_END */
@@ -4736,6 +4743,12 @@ status_t SurfaceFlinger::setTransactionState(
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
const std::vector<uint64_t>& mergedTransactionIds) {
ATRACE_CALL();
+ /* QTI_BEGIN */
+ std::unique_lock<std::mutex> lck (mSmomoMutex, std::defer_lock);
+ if (mQtiSFExtnIntf->qtiIsSmomoOptimalRefreshActive()) {
+ lck.lock();
+ }
+ /* QTI_END */
IPCThreadState* ipc = IPCThreadState::self();
const int originPid = ipc->getCallingPid();
@@ -5927,6 +5940,9 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
strerror(-lock.status), lock.status);
ALOGW("Dumping without lock after timeout: %s (%d)",
strerror(-lock.status), lock.status);
+ /* QTI_BEGIN */
+ return NO_ERROR;
+ /* QTI_END */
}
if (const auto it = dumpers.find(flag); it != dumpers.end()) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 60df5a734a..47176ca75d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1465,6 +1465,7 @@ private:
/* QTI_BEGIN */
surfaceflingerextension::QtiSurfaceFlingerExtensionIntf* mQtiSFExtnIntf = nullptr;
+ std::mutex mSmomoMutex;
/* QTI_END */
TransactionHandler mTransactionHandler;