diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2024-01-31 13:59:43 -0800 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2024-01-31 13:59:43 -0800 |
commit | be88ab83e4197c6ffca932ecae7d4718a5779dd9 (patch) | |
tree | 0471b0c83fefee1c2a9567c58b839985242ebcbc | |
parent | c1e6674635ed20886a22218c11fdbef5f935c498 (diff) | |
parent | c20a9a488f23bfece8b179f423f2448d43fe5866 (diff) |
Merge c20a9a488f23bfece8b179f423f2448d43fe5866 on remote branch
Change-Id: Iec61256b5f290e901a69ee8fb9aea54b2841edcf
7 files changed, 259 insertions, 21 deletions
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/QtiExtension/QtiNullExtension.cpp b/services/surfaceflinger/QtiExtension/QtiNullExtension.cpp index 6ac1ca3bf9..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" @@ -109,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 */ @@ -204,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 c334458356..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 @@ -145,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/QtiSurfaceFlingerExtension.cpp b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtension.cpp index cbf39468fa..e53fbea382 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; @@ -2134,6 +2139,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 16b2c26289..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 @@ -253,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); diff --git a/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h b/services/surfaceflinger/QtiExtension/QtiSurfaceFlingerExtensionIntf.h index 5781672d80..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; @@ -178,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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index db0e331231..efed751f2a 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"); @@ -2733,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); @@ -3084,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); @@ -5895,6 +5905,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(); @@ -5949,22 +5966,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 */ - return NO_ERROR; - /* QTI_END */ + /* 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 */ } } |