summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralk3pInjection <webmaster@raspii.tech>2024-03-01 21:00:08 +0800
committeralk3pInjection <webmaster@raspii.tech>2024-03-01 21:00:08 +0800
commit266dbdd5d119ba31772a09a746cd7d964a4f5e3d (patch)
tree1a539faf87b71b3e3785f95f8b3601bb5bc92989
parent10f58ef0c1d3aaf020eba1115138df8ffba12cdd (diff)
parentd9a76c23430a511c7da35c2785277146a1753e14 (diff)
Merge tag 'LA.QSSI.14.0.r1-13000-qssi.0' into umineko
LA.QSSI.14.0.r1-13000-qssi.0 Change-Id: Idcdd0de7bd963b89c0f88c8e383dc3ab47f2a748
-rw-r--r--libs/binder/MemoryHeapBase.cpp4
-rw-r--r--libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp13
-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--libs/renderengine/skia/SkiaRenderEngine.cpp13
-rw-r--r--services/sensorservice/SensorService.cpp7
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp45
-rw-r--r--services/surfaceflinger/DisplayDevice.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp10
-rw-r--r--services/surfaceflinger/Layer.cpp35
-rw-r--r--services/surfaceflinger/QtiExtension/QtiNullExtension.cpp13
-rw-r--r--services/surfaceflinger/QtiExtension/QtiNullExtension.h7
-rw-r--r--services/surfaceflinger/QtiExtension/QtiPhaseOffsetsExtension.cpp2
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp256
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h20
-rw-r--r--services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h8
-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.cpp115
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h6
25 files changed, 695 insertions, 92 deletions
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 8fe1d2bb3d..34e747ef21 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -73,8 +73,8 @@ MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
ALOGV("MemoryHeapBase: Attempting to force MemFD");
fd = memfd_create_region(name ? name : "MemoryHeapBase", size);
if (fd < 0 || (mapfd(fd, true, size) != NO_ERROR)) return;
- const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) |
- ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL);
+ const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) | F_SEAL_GROW |
+ F_SEAL_SHRINK | ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL);
if (SEAL_FLAGS && (fcntl(fd, F_ADD_SEALS, SEAL_FLAGS) == -1)) {
ALOGE("MemoryHeapBase: MemFD %s sealing with flags %x failed with error %s", name,
SEAL_FLAGS, strerror(errno));
diff --git a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
index 278dd2bf81..140270f5a1 100644
--- a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
+++ b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
@@ -37,7 +37,8 @@ TEST(MemoryHeapBase, MemfdSealed) {
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdUnsealed) {
@@ -48,7 +49,8 @@ TEST(MemoryHeapBase, MemfdUnsealed) {
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), 0);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdSealedProtected) {
@@ -59,7 +61,9 @@ TEST(MemoryHeapBase, MemfdSealedProtected) {
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS),
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdUnsealedProtected) {
@@ -71,7 +75,8 @@ TEST(MemoryHeapBase, MemfdUnsealedProtected) {
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
#else
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/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 9e9df5216f..edf734271a 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -397,12 +397,10 @@ void SkiaRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
}
// We don't attempt to map a buffer if the buffer contains protected content. In GL this is
// important because GPU resources for protected buffers are much more limited. (In Vk we
- // simply match the existing behavior for protected buffers.) In Vk, we never cache any
- // buffers while in a protected context, since Vk cannot share across contexts, and protected
- // is less common.
+ // simply match the existing behavior for protected buffers.) We also never cache any
+ // buffers while in a protected context.
const bool isProtectedBuffer = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
- if (isProtectedBuffer ||
- (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && isProtected())) {
+ if (isProtectedBuffer || isProtected()) {
return;
}
ATRACE_CALL();
@@ -467,9 +465,8 @@ void SkiaRenderEngine::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
std::shared_ptr<AutoBackendTexture::LocalRef> SkiaRenderEngine::getOrCreateBackendTexture(
const sp<GraphicBuffer>& buffer, bool isOutputBuffer) {
- // Do not lookup the buffer in the cache for protected contexts with the SkiaVk back-end
- if (mRenderEngineType == RenderEngineType::SKIA_GL_THREADED ||
- (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && !isProtected())) {
+ // Do not lookup the buffer in the cache for protected contexts
+ if (!isProtected()) {
if (const auto& it = mTextureCache.find(buffer->getId()); it != mTextureCache.end()) {
return it->second;
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 90d75414d6..398d60242b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1055,12 +1055,7 @@ bool SensorService::threadLoop() {
if (count < 0) {
if(count == DEAD_OBJECT && device.isReconnecting()) {
device.reconnect();
- // There are no "real" events at this point, but do not skip the rest of the loop
- // if there are pending runtime events.
- Mutex::Autolock _l(&mLock);
- if (mRuntimeSensorEventQueue.empty()) {
- continue;
- }
+ continue;
} else {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index f0b6763cd5..fb851e653c 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 */
+ ui::Transform scale;
+ ui::Transform rotationTransform = getTransform();
+ scale.set(1, 0, 0, 1);
+ if(mUseFbScaling && isPrimary()){ //use fb_scaling
+ auto currMode = refreshRateSelector().getActiveMode();
+ rotationTransform.set(getTransform().getOrientation(), currMode.modePtr->getWidth(),
+ currMode.modePtr->getHeight());
+ 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/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 6c3c67f3a6..f126710cbc 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -815,6 +815,16 @@ Error AidlComposer::presentOrValidateDisplay(Display display, nsecs_t expectedPr
*state = translate<uint32_t>(*result);
+ /* QTI_BEGIN */
+ if (*state == 2) {
+ auto fence = reader->get().takePresentFence(displayId);
+ // take ownership
+ *outPresentFence = fence.get();
+ *fence.getR() = -1;
+ reader->get().hasChanges(displayId, outNumTypes, outNumRequests);
+ }
+ /* QTI_END */
+
if (*result == PresentOrValidate::Result::Presented) {
auto fence = reader->get().takePresentFence(displayId);
// take ownership
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4f02e4b8d3..b894396cee 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -16,7 +16,7 @@
/* Changes from Qualcomm Innovation Center are provided under the following license:
*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
@@ -3511,31 +3511,26 @@ void Layer::gatherBufferInfo() {
{
ATRACE_NAME("getDataspace");
err = mapper.getDataspace(mBufferInfo.mBuffer->getBuffer()->handle, &dataspace);
+ /* QTI_BEGIN */
+ if (dataspace == ui::Dataspace::UNKNOWN) {
+ ALOGW("%s: Received unknown dataspace from gralloc", __func__);
+ }
+ /* QTI_END */
}
- if (err != OK || dataspace != mBufferInfo.mDataspace) {
+ if ((err != OK || dataspace != mBufferInfo.mDataspace)
+ /* QTI_BEGIN */
+ && dataspace != ui::Dataspace::UNKNOWN) {
+ /* QTI_END */
{
ATRACE_NAME("setDataspace");
err = mapper.setDataspace(mBufferInfo.mBuffer->getBuffer()->handle,
static_cast<ui::Dataspace>(mBufferInfo.mDataspace));
}
-
- // Some GPU drivers may cache gralloc metadata which means before we composite we need
- // to upsert RenderEngine's caches. Put in a special workaround to be backwards
- // compatible with old vendors, with a ticking clock.
- static const int32_t kVendorVersion =
- base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
- if (const auto format =
- static_cast<aidl::android::hardware::graphics::common::PixelFormat>(
- mBufferInfo.mBuffer->getPixelFormat());
- err == OK && kVendorVersion < __ANDROID_API_U__ &&
- (format ==
- aidl::android::hardware::graphics::common::PixelFormat::
- IMPLEMENTATION_DEFINED ||
- format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_420_888 ||
- format == aidl::android::hardware::graphics::common::PixelFormat::YV12 ||
- format == aidl::android::hardware::graphics::common::PixelFormat::YCBCR_P010)) {
- mBufferInfo.mBuffer->remapBuffer();
- }
+ /* QTI_BEGIN */
+ // GPU drivers cache gralloc metadata which means before we composite we need
+ // to upsert RenderEngine's cache.
+ mBufferInfo.mBuffer->remapBuffer();
+ /* QTI_END */
}
}
if (lastDataspace != mBufferInfo.mDataspace) {
diff --git a/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp b/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
index 9e158dee63..54c199bc2d 100644
--- a/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
+++ b/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+/* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "QtiNullExtension.h"
@@ -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.
*/
@@ -107,6 +109,11 @@ status_t QtiNullExtension::qtiBinderSetPanelBrightnessTiled(uint64_t displayId,
status_t QtiNullExtension::qtiBinderSetWideModePreference(uint64_t displayId, int32_t pref) {
return OK;
}
+status_t QtiNullExtension::qtiDoDumpContinuous(int fd, const DumpArgs& args) {
+ return OK;
+}
+void QtiNullExtension::qtiDumpDrawCycle(bool prePrepare) {}
+
/*
* Methods for Virtual, WiFi, and Secure Displays
*/
@@ -168,6 +175,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
@@ -199,5 +209,6 @@ bool QtiNullExtension::qtiFbScalingOnDisplayChange(const wp<IBinder>& displayTok
}
void QtiNullExtension::qtiFbScalingOnPowerChange(sp<DisplayDevice> display) {}
+void QtiNullExtension::qtiDumpMini(std::string& result) {}
} // namespace android::surfaceflingerextension
diff --git a/services/surfaceflinger/QtiExtension/QtiNullExtension.h b/services/surfaceflinger/QtiExtension/QtiNullExtension.h
index f961d95d44..755c2f31ac 100644
--- a/services/surfaceflinger/QtiExtension/QtiNullExtension.h
+++ b/services/surfaceflinger/QtiExtension/QtiNullExtension.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+/* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#pragma once
@@ -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
@@ -143,6 +145,9 @@ public:
bool qtiFbScalingOnDisplayChange(const wp<IBinder>& displayToken, sp<DisplayDevice> display,
const DisplayDeviceState& drawingState) override;
void qtiFbScalingOnPowerChange(sp<DisplayDevice> display) override;
+ void qtiDumpMini(std::string& result) override;
+ status_t qtiDoDumpContinuous(int fd, const DumpArgs& args) override;
+ void qtiDumpDrawCycle(bool prePrepare) override;
private:
SurfaceFlinger* mQtiFlinger = nullptr;
diff --git a/services/surfaceflinger/QtiExtension/QtiPhaseOffsetsExtension.cpp b/services/surfaceflinger/QtiExtension/QtiPhaseOffsetsExtension.cpp
index bda4a201b8..31eed734f5 100644
--- a/services/surfaceflinger/QtiExtension/QtiPhaseOffsetsExtension.cpp
+++ b/services/surfaceflinger/QtiExtension/QtiPhaseOffsetsExtension.cpp
@@ -54,7 +54,7 @@ void QtiPhaseOffsetsExtension::qtiUpdateSfOffsets(
std::lock_guard lock(mQtiVsyncConfiguration->mLock);
for (auto& item : *advancedSfOffsets) {
float fps = item.first;
- auto mOffsetsCache = mQtiVsyncConfiguration->mOffsetsCache;
+ auto& mOffsetsCache = mQtiVsyncConfiguration->mOffsetsCache;
auto iter = mOffsetsCache.begin();
for (iter = mOffsetsCache.begin(); iter != mOffsetsCache.end(); iter++) {
float candidateFps = iter->first.getValue();
diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
index be4f21b0a9..d668b22f87 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+/* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
// #define LOG_NDEBUG 0
@@ -28,9 +28,14 @@
#include <compositionengine/impl/Display.h>
#include <ui/DisplayStatInfo.h>
#include <vector>
+#include <sys/stat.h>
+#include <fstream>
+#include <ui/GraphicBufferAllocator.h>
+#include <layerproto/LayerProtoParser.h>
using aidl::vendor::qti::hardware::display::config::IDisplayConfig;
using vendor::qti::hardware::display::composer::V3_1::IQtiComposerClient;
+using android::base::StringAppendF;
using android::compositionengine::Display;
using android::compositionengineextension::QtiRenderSurfaceExtension;
@@ -190,7 +195,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 +216,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 +475,10 @@ void QtiSurfaceFlingerExtension::qtiUpdateBufferData(bool qtiLatchMediaContent,
}
}
+void QtiSurfaceFlingerExtension::qtiOnComposerHalRefresh() {
+ mComposerRefreshNotified = true;
+}
+
/*
* Methods that call the FeatureManager APIs.
*/
@@ -548,6 +561,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;
@@ -1106,7 +1124,9 @@ void QtiSurfaceFlingerExtension::qtiCheckVirtualDisplayHint(const Vector<Display
bool createVirtualDisplay = false;
int width = 0, height = 0, format = 0;
{
- Mutex::Autolock lock(mQtiFlinger->mStateLock);
+ bool needLock = (!mQtiFlinger->mRequestDisplayModeFlag ||
+ (mQtiFlinger->mFlagThread != std::this_thread::get_id()));
+ ConditionalLock lock(mQtiFlinger->mStateLock, needLock == true);
for (const DisplayState& s : displays) {
const ssize_t index = mQtiFlinger->mCurrentState.displays.indexOfKey(s.token);
if (index < 0) continue;
@@ -1376,10 +1396,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 +1482,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 +1582,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();
}
}
@@ -1622,7 +1673,10 @@ void QtiSurfaceFlingerExtension::qtiUpdateSmomoLayerStackId(hal::HWDisplayId hwc
}
uint32_t QtiSurfaceFlingerExtension::qtiGetLayerClass(std::string mName) {
- if (mQtiLayerExt) {
+ bool mUseLayerExt =
+ mQtiFeatureManager->qtiIsExtensionFeatureEnabled(QtiFeature::kLayerExtension);
+
+ if (mUseLayerExt && mQtiLayerExt) {
uint32_t layerClass = static_cast<uint32_t>(mQtiLayerExt->GetLayerClass(mName));
return layerClass;
}
@@ -1962,36 +2016,23 @@ void QtiSurfaceFlingerExtension::qtiSetFrameBufferSizeForScaling(
auto display = displayDevice->getCompositionDisplay();
int newWidth = currentState.layerStackSpaceRect.width();
int newHeight = currentState.layerStackSpaceRect.height();
- int currentWidth = drawingState.layerStackSpaceRect.width();
- int currentHeight = drawingState.layerStackSpaceRect.height();
int displayWidth = displayDevice->getWidth();
int displayHeight = displayDevice->getHeight();
- bool update_needed = false;
- ALOGV("%s: newWidth %d newHeight %d currentWidth %d currentHeight %d displayWidth %d "
- "displayHeight %d",
- __func__, newWidth, newHeight, currentWidth, currentHeight, displayWidth, displayHeight);
+ ALOGV("%s: newWidth %d newHeight %d displayWidth %d displayHeight %d",
+ __func__, newWidth, newHeight, displayWidth, displayHeight);
- if (newWidth != currentWidth || newHeight != currentHeight) {
- update_needed = true;
+ if (newWidth != displayWidth || newHeight != displayHeight) {
if (!((newWidth > newHeight && displayWidth > displayHeight) ||
(newWidth < newHeight && displayWidth < displayHeight))) {
std::swap(newWidth, newHeight);
ALOGV("%s: Width %d or height %d was updated. Swap the values of newWidth %d and "
"newHeight %d",
- __func__, (newWidth != currentWidth), (newHeight != currentHeight), newWidth,
+ __func__, (newWidth != displayWidth), (newHeight != displayHeight), newWidth,
newHeight);
}
}
- if (displayDevice->getWidth() == newWidth && displayDevice->getHeight() == newHeight &&
- !update_needed) {
- ALOGV("%s: No changes on the configuration", __func__);
- displayDevice->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
- currentState.orientedDisplaySpaceRect);
- return;
- }
-
if (newWidth > 0 && newHeight > 0) {
currentState.width = static_cast<uint32_t>(newWidth);
currentState.height = static_cast<uint32_t>(newHeight);
@@ -2000,6 +2041,14 @@ void QtiSurfaceFlingerExtension::qtiSetFrameBufferSizeForScaling(
}
currentState.orientedDisplaySpaceRect = currentState.layerStackSpaceRect;
+
+ if (displayWidth == newWidth && displayHeight == newHeight) {
+ ALOGV("%s: No changes on the configuration", __func__);
+ displayDevice->setProjection(currentState.orientation, currentState.layerStackSpaceRect,
+ currentState.orientedDisplaySpaceRect);
+ return;
+ }
+
ALOGV("%s: Update currentState's orientedDisplaySpaceRect left %f top %f right %f bottom %f",
__func__, currentState.orientedDisplaySpaceRect.left,
currentState.orientedDisplaySpaceRect.top, currentState.orientedDisplaySpaceRect.right,
@@ -2027,6 +2076,7 @@ void QtiSurfaceFlingerExtension::qtiSetFrameBufferSizeForScaling(
} else {
mQtiDisplaySizeChanged = true;
}
+ mQtiFlinger->setTransactionFlags(eDisplayTransactionNeeded);
}
}
@@ -2088,6 +2138,164 @@ void QtiSurfaceFlingerExtension::qtiFbScalingOnPowerChange(sp<DisplayDevice> dis
mQtiDisplaySizeChanged = false;
}
+void QtiSurfaceFlingerExtension::qtiDumpMini(std::string& result) {
+ Mutex::Autolock lock(mQtiFlinger->mStateLock);
+ for (const auto& [token, display] : mQtiFlinger->mDisplays) {
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+ if (!displayId) {
+ continue;
+ }
+ StringAppendF(&result, "Display %s HWC layers:\n", to_string(*displayId).c_str());
+ Layer::miniDumpHeader(result);
+ const DisplayDevice& displayDevice = *display;
+ mQtiFlinger->mDrawingState.traverseInZOrder(
+ [&](Layer* layer) { layer->miniDump(result, displayDevice); });
+ result.append("\n");
+ }
+
+ result.append("h/w composer state:\n");
+ StringAppendF(&result, " h/w composer %s\n",
+ mQtiFlinger->mDebugDisableHWC ? "disabled" : "enabled");
+ mQtiFlinger->getHwComposer().dump(result);
+}
+
+status_t QtiSurfaceFlingerExtension::qtiDoDumpContinuous(int fd, const DumpArgs& args) {
+ // Format: adb shell dumpsys SurfaceFlinger --file --nolimit
+ size_t numArgs = args.size();
+ status_t err = NO_ERROR;
+
+ if (args[0] == String16("--allocated_buffers")) {
+ std::string dumpsys;
+ GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+ alloc.dump(dumpsys);
+ write(fd, dumpsys.c_str(), dumpsys.size());
+ return NO_ERROR;
+ }
+
+ Mutex::Autolock _l(mFileDump.lock);
+ // Same command is used to start and end dump.
+ mFileDump.running = !mFileDump.running;
+ // selection of full dumpsys or not (defualt, dumpsys will be minimum required)
+ // Format: adb shell dumpsys SurfaceFlinger --file --nolimit --full-dump
+ if (mFileDump.running) {
+ std::ofstream ofs;
+ ofs.open(mFileDump.name, std::ofstream::out | std::ofstream::trunc);
+ if (!ofs) {
+ mFileDump.running = false;
+ err = UNKNOWN_ERROR;
+ } else {
+ ofs.close();
+ mFileDump.position = 0;
+ if (numArgs >= 2 && (args[1] == String16("--nolimit"))) {
+ mFileDump.noLimit = true;
+ if (numArgs == 3 && args[2] == String16("--full-dump"))
+ mFileDump.fullDump = true;
+ } else {
+ mFileDump.noLimit = false;
+ mFileDump.fullDump = false;
+ }
+ }
+ }
+
+ std::string result;
+ result += mFileDump.running ? "Start" : "End";
+ result += mFileDump.noLimit ? " unlimited" : " fixed limit";
+ result += " dumpsys to file : ";
+ result += mFileDump.name;
+ result += "\n";
+ write(fd, result.c_str(), result.size());
+
+ return NO_ERROR;
+}
+
+void QtiSurfaceFlingerExtension::qtiDumpDrawCycle(bool prePrepare) {
+ Mutex::Autolock _l(mFileDump.lock);
+
+ // User might stop dump collection in middle of prepare & commit.
+ // Collect dumpsys again after commit and replace.
+ if (!mFileDump.running && !mFileDump.replaceAfterCommit) {
+ return;
+ }
+ Vector<String16> args;
+ std::string dumpsys;
+ {
+ if (mFileDump.fullDump) {
+ Mutex::Autolock lock(mQtiFlinger->mStateLock);
+ std::string compositionLayers;
+ StringAppendF(&compositionLayers, "Composition layers\n");
+ mQtiFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
+ auto* compositionState = layer->getCompositionState();
+ if (!compositionState || !compositionState->isVisible) return;
+ android::base::StringAppendF(&compositionLayers, "* Layer %p (%s)\n", layer,
+ layer->getDebugName() ? layer->getDebugName()
+ : "<unknown>");
+ compositionState->dump(compositionLayers);
+ });
+ mQtiFlinger->dumpAllLocked(args, compositionLayers, dumpsys);
+ } else {
+ qtiDumpMini(dumpsys);
+ }
+ }
+
+ if (mFileDump.fullDump) {
+ LayersTraceFileProto traceFileProto = mQtiFlinger->mLayerTracing.createTraceFileProto();
+ LayersTraceProto* layersTrace = traceFileProto.add_entry();
+ LayersProto layersProto = mQtiFlinger->dumpDrawingStateProto(LayerTracing::TRACE_ALL);
+ layersTrace->mutable_layers()->Swap(&layersProto);
+ auto displayProtos = mQtiFlinger->dumpDisplayProto();
+ layersTrace->mutable_displays()->Swap(&displayProtos);
+ const auto layerTree = LayerProtoParser::generateLayerTree(layersTrace->layers());
+ dumpsys.append(LayerProtoParser::layerTreeToString(layerTree));
+ dumpsys.append("\n");
+ dumpsys.append("Offscreen Layers:\n");
+ for (Layer* offscreenLayer : mQtiFlinger->mOffscreenLayers) {
+ offscreenLayer->traverse(LayerVector::StateSet::Drawing,
+ [&](Layer* layer) {
+ layer->dumpOffscreenDebugInfo(dumpsys);});
+ }
+ }
+
+ char timeStamp[32];
+ char dataSize[32];
+ char hms[32];
+ long millis;
+ struct timeval tv;
+ struct tm *ptm;
+ gettimeofday(&tv, NULL);
+ ptm = localtime(&tv.tv_sec);
+ strftime (hms, sizeof (hms), "%H:%M:%S", ptm);
+ millis = tv.tv_usec / 1000;
+ snprintf(timeStamp, sizeof(timeStamp), "Timestamp: %s.%03ld", hms, millis);
+ snprintf(dataSize, sizeof(dataSize), "Size: %8zu", dumpsys.size());
+ std::fstream fs;
+ fs.open(mFileDump.name, std::ios::app);
+ if (!fs) {
+ ALOGE("Failed to open %s file for dumpsys", mFileDump.name);
+ return;
+ }
+ // Format:
+ // | start code | after commit? | time stamp | dump size | dump data |
+ fs.seekp(mFileDump.position, std::ios::beg);
+ fs << "#@#@-- DUMPSYS START --@#@#" << std::endl;
+ fs << "PostCommit: " << ( prePrepare ? "false" : "true" ) << std::endl;
+ fs << timeStamp << std::endl;
+ fs << dataSize << std::endl;
+ fs << dumpsys << std::endl;
+
+ if (prePrepare) {
+ mFileDump.replaceAfterCommit = true;
+ } else {
+ mFileDump.replaceAfterCommit = false;
+ // Reposition only after commit.
+ // Keep file size to appx 20 MB limit by default, wrap around if exceeds.
+ mFileDump.position = fs.tellp();
+ if (!mFileDump.noLimit && (mFileDump.position > (20 * 1024 * 1024))) {
+ mFileDump.position = 0;
+ }
+ }
+ fs.close();
+}
+
void QtiSurfaceFlingerExtension::qtiAllowIdleFallback() {
bool allowIdleFallback =
mQtiFeatureManager->qtiIsExtensionFeatureEnabled(QtiFeature::kIdleFallback);
diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
index ba5880feca..71acbad99a 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+/* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#pragma once
@@ -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
@@ -250,8 +253,21 @@ public:
bool qtiFbScalingOnDisplayChange(const wp<IBinder>& displayToken, sp<DisplayDevice> display,
const DisplayDeviceState& drawingState) override;
void qtiFbScalingOnPowerChange(sp<DisplayDevice> display) override;
+ void qtiDumpMini(std::string& result) override;
+ status_t qtiDoDumpContinuous(int fd, const DumpArgs& args) override;
+ void qtiDumpDrawCycle(bool prePrepare) override;
void qtiAllowIdleFallback();
+ struct {
+ Mutex lock;
+ const char *name = "/data/misc/wmtrace/dumpsys.txt";
+ bool running = false;
+ bool noLimit = false;
+ bool fullDump = false;
+ bool replaceAfterCommit = false;
+ long long int position = 0;
+ } mFileDump;
+
private:
SmomoIntf* qtiGetSmomoInstance(const uint32_t layerStackId) const;
bool qtiIsInternalDisplay(const sp<DisplayDevice>& display);
@@ -268,6 +284,7 @@ private:
QtiWorkDurationsExtension* mQtiWorkDurationsExtn = nullptr;
QtiDolphinWrapper* mQtiDolphinWrapper = nullptr;
+ bool mQtiSmomoOptimalRefreshActive = false;
bool mQtiEnabledIDC = false;
bool mQtiInitVsyncConfigurationExtn = false;
bool mQtiInternalPresentationDisplays = false;
@@ -281,6 +298,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..7facf7f3ca 100644
--- a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h
+++ b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+/* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#pragma once
@@ -15,6 +15,7 @@ class DisplayExtnIntf;
} // namespace composer
using android::scheduler::VsyncConfiguration;
namespace android::surfaceflingerextension {
+using DumpArgs = Vector<String16>;
class QtiHWComposerExtensionIntf;
@@ -69,6 +70,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 +152,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
@@ -176,6 +179,9 @@ public:
sp<DisplayDevice> display,
const DisplayDeviceState& drawingState) = 0;
virtual void qtiFbScalingOnPowerChange(sp<DisplayDevice> display) = 0;
+ virtual void qtiDumpMini(std::string& result) = 0;
+ virtual status_t qtiDoDumpContinuous(int fd, const DumpArgs& args) = 0;
+ virtual void qtiDumpDrawCycle(bool prePrepare) = 0;
};
} // namespace android::surfaceflingerextension
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 02b9e49f48..f10e07b4ee 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -16,7 +16,7 @@
/* Changes from Qualcomm Innovation Center are provided under the following license:
*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
@@ -861,10 +861,6 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
- if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
- enableHalVirtualDisplays(true);
- }
-
// Process hotplug for displays connected at boot.
LOG_ALWAYS_FATAL_IF(!configureLocked(),
"Initial display configuration failed: HWC did not hotplug");
@@ -938,6 +934,11 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
mVsyncConfiguration.get(), getHwComposer().getComposer());
surfaceflingerextension::QtiExtensionContext::instance().setCompositionEngine(
&getCompositionEngine());
+
+ if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
+ enableHalVirtualDisplays(true);
+ }
+
mQtiSFExtnIntf->qtiStartUnifiedDraw();
/* QTI_END */
ALOGV("Done initializing");
@@ -2155,6 +2156,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 +2430,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 */
@@ -2726,6 +2734,11 @@ void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId)
std::vector<std::pair<Layer*, LayerFE*>> layers =
moveSnapshotsToCompositionArgs(refreshArgs, /*cursorOnly=*/false, vsyncId.value);
+
+ /* QTI_BEGIN */
+ mQtiSFExtnIntf->qtiDumpDrawCycle(true);
+ /* QTI_END */
+
mCompositionEngine->present(refreshArgs);
moveSnapshotsFromCompositionArgs(refreshArgs, layers);
@@ -3077,6 +3090,10 @@ void SurfaceFlinger::postComposition(nsecs_t callTime) {
}
}
+ /* QTI_BEGIN */
+ mQtiSFExtnIntf->qtiDumpDrawCycle(false);
+ /* QTI_END */
+
const size_t sfConnections = mScheduler->getEventThreadConnectionCount(mSfConnectionHandle);
const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle);
mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections);
@@ -3681,6 +3698,9 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
if (display->isVirtual()) {
releaseVirtualDisplay(display->getVirtualId());
}
+ /* QTI_BEGIN */
+ mQtiSFExtnIntf->qtiDestroySmomoInstance(display);
+ /* QTI_END */
}
mDisplays.erase(displayToken);
@@ -4065,6 +4085,14 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest
// Scheduler::chooseRefreshRateForContent
ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
+ /* QTI_BEGIN */
+ // Setting mRequestDisplayModeFlag as true and storing thread Id to avoid acquiring the same
+ // mutex again in a single thread
+ if (std::this_thread::get_id() != mMainThreadId) {
+ mRequestDisplayModeFlag = true;
+ mFlagThread = std::this_thread::get_id();
+ }
+ /* QTI_END */
for (auto& request : modeRequests) {
const auto& modePtr = request.mode.modePtr;
@@ -4097,6 +4125,12 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest
to_string(display->getId()).c_str());
}
}
+ /* QTI_BEGIN */
+ if (std::this_thread::get_id() != mMainThreadId) {
+ mRequestDisplayModeFlag = false;
+ mFlagThread = mMainThreadId;
+ }
+ /* QTI_END */
}
void SurfaceFlinger::triggerOnFrameRateOverridesChanged() {
@@ -4576,24 +4610,25 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC
}
/* QTI_END */
+ /* QTI_BEGIN */
+ bool qtiLatchMediaContent = mQtiSFExtnIntf->qtiLatchMediaContent(layer);
+ /* QTI_END */
+
// ignore the acquire fence if LatchUnsignaledConfig::Always is set.
- const bool checkAcquireFence = enableLatchUnsignaledConfig != LatchUnsignaledConfig::Always;
+ const bool checkAcquireFence = enableLatchUnsignaledConfig != LatchUnsignaledConfig::Always
+ /* QTI_BEGIN */ || qtiLatchMediaContent /* QTI_END */;
const bool acquireFenceAvailable = s.bufferData &&
s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
s.bufferData->acquireFence;
const bool fenceSignaled = !checkAcquireFence || !acquireFenceAvailable ||
s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
- /* QTI_BEGIN */
- bool qtiLatchMediaContent = mQtiSFExtnIntf->qtiLatchMediaContent(layer);
- /* QTI_END */
-
if (!fenceSignaled) {
// check fence status
const bool allowLatchUnsignaled =
shouldLatchUnsignaled(layer, s, transaction.states.size(),
flushState.firstTransaction);
- if (allowLatchUnsignaled /* QTI_BEGIN */ || qtiLatchMediaContent /* QTI_END */) {
+ if (allowLatchUnsignaled /* QTI_BEGIN */ || !qtiLatchMediaContent /* QTI_END */) {
ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
layer->getDebugName());
ready = TransactionReadiness::NotReadyUnsignaled;
@@ -4735,6 +4770,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();
@@ -4797,7 +4838,9 @@ status_t SurfaceFlinger::setTransactionState(
layerName.c_str(), transactionId);
/* QTI_BEGIN */
- mQtiSFExtnIntf->qtiDolphinTrackBufferIncrement(layerName.c_str());
+ if (!(flags & eOneWay)) {
+ mQtiSFExtnIntf->qtiDolphinTrackBufferIncrement(layerName.c_str());
+ }
mQtiSFExtnIntf->qtiUpdateSmomoLayerInfo(layer, desiredPresentTime, isAutoTimestamp,
resolvedState.externalTexture,
@@ -5866,6 +5909,13 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
}
status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
+ /* QTI_BEGIN */
+ size_t numArgs = args.size();
+ if (numArgs && ((args[0] == String16("--file")) ||
+ (args[0] == String16("--allocated_buffers")))) {
+ return mQtiSFExtnIntf->qtiDoDumpContinuous(fd, args);
+ }
+ /* QTI_END */
std::string result;
IPCThreadState* ipc = IPCThreadState::self();
@@ -5920,19 +5970,44 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {
bool dumpLayers = true;
{
- TimedLock lock(mStateLock, s2ns(1), __func__);
- if (!lock.locked()) {
- StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
- strerror(-lock.status), lock.status);
- ALOGW("Dumping without lock after timeout: %s (%d)",
- strerror(-lock.status), lock.status);
+ /* QTI_BEGIN */
+ {
+ /* QTI_END */
+ TimedLock lock(mStateLock, s2ns(1), __func__);
+ if (!lock.locked()) {
+ StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",
+ 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 */
+ }
+ /* QTI_BEGIN */
}
+ /* QTI_END */
if (const auto it = dumpers.find(flag); it != dumpers.end()) {
- (it->second)(args, asProto, result);
+ /* QTI_BEGIN */
+ TimedLock lock(mStateLock, s2ns(1), __func__);
+ if (lock.locked()) {
+ (it->second)(args, asProto, result);
+ }
+ /* QTI_END */
dumpLayers = false;
} else if (!asProto) {
- dumpAllLocked(args, compositionLayers, result);
+ /* QTI_BEGIN */
+ // selection of mini dumpsys (Format: adb shell dumpsys SurfaceFlinger --mini)
+ if (numArgs && ((args[0] == String16("--mini")))) {
+ mQtiSFExtnIntf->qtiDumpMini(result);
+ dumpLayers = false;
+ } else {
+ TimedLock lock(mStateLock, s2ns(1), __func__);
+ if (lock.locked()) {
+ dumpAllLocked(args, compositionLayers, result);
+ }
+ }
+ /* QTI_END */
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 60df5a734a..c50f4b8c80 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -353,6 +353,11 @@ public:
return sActiveDisplayRotationFlags;
}
+ /* QTI_BEGIN */
+ bool mRequestDisplayModeFlag = false;
+ std::thread::id mFlagThread = std::this_thread::get_id();
+ /* QTI_END */
+
protected:
// We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger();
@@ -1465,6 +1470,7 @@ private:
/* QTI_BEGIN */
surfaceflingerextension::QtiSurfaceFlingerExtensionIntf* mQtiSFExtnIntf = nullptr;
+ std::mutex mSmomoMutex;
/* QTI_END */
TransactionHandler mTransactionHandler;