diff options
author | alk3pInjection <webmaster@raspii.tech> | 2024-03-01 21:00:08 +0800 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2024-03-01 21:00:08 +0800 |
commit | 266dbdd5d119ba31772a09a746cd7d964a4f5e3d (patch) | |
tree | 1a539faf87b71b3e3785f95f8b3601bb5bc92989 | |
parent | 10f58ef0c1d3aaf020eba1115138df8ffba12cdd (diff) | |
parent | d9a76c23430a511c7da35c2785277146a1753e14 (diff) |
Merge tag 'LA.QSSI.14.0.r1-13000-qssi.0' into umineko
LA.QSSI.14.0.r1-13000-qssi.0
Change-Id: Idcdd0de7bd963b89c0f88c8e383dc3ab47f2a748
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; |