Skip to content

Commit 734f288

Browse files
committed
Trace critical workloads
Create a new trace track and trace all important work that happens on the main thread. Keep track of changes in workload as transaction are queued and committed to infer when the CPU load will increase from the last frame. This CL only logs the workload. Flag: EXEMPT logs Bug: 333623207 Test: perfetto Change-Id: Ib423d1968545adc89172bd0e40fbde2a31b46ddf
1 parent a1635a6 commit 734f288

17 files changed

Lines changed: 392 additions & 3 deletions

File tree

libs/gui/include/gui/LayerState.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ struct layer_state_t {
302302
static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES |
303303
layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged;
304304

305+
// Changes that force GPU composition.
306+
static constexpr uint64_t COMPOSITION_EFFECTS = layer_state_t::eBackgroundBlurRadiusChanged |
307+
layer_state_t::eBlurRegionsChanged | layer_state_t::eCornerRadiusChanged |
308+
layer_state_t::eShadowRadiusChanged | layer_state_t::eStretchChanged;
309+
305310
bool hasValidBuffer() const;
306311
void sanitize(int32_t permissions);
307312

services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
#include <utils/RefBase.h>
3737
#include <utils/Timers.h>
3838

39+
namespace aidl::android::hardware::graphics::composer3 {
40+
enum class Composition;
41+
}
42+
3943
namespace android {
4044

4145
class Fence;
@@ -176,6 +180,11 @@ class LayerFE : public virtual RefBase {
176180
// Whether the layer should be rendered with rounded corners.
177181
virtual bool hasRoundedCorners() const = 0;
178182
virtual void setWasClientComposed(const sp<Fence>&) {}
183+
virtual void setHwcCompositionType(
184+
aidl::android::hardware::graphics::composer3::Composition) = 0;
185+
virtual aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
186+
const = 0;
187+
179188
virtual const gui::LayerMetadata* getMetadata() const = 0;
180189
virtual const gui::LayerMetadata* getRelativeMetadata() const = 0;
181190
};

services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class LayerFE : public compositionengine::LayerFE {
5959
MOCK_CONST_METHOD0(getMetadata, gui::LayerMetadata*());
6060
MOCK_CONST_METHOD0(getRelativeMetadata, gui::LayerMetadata*());
6161
MOCK_METHOD0(onPictureProfileCommitted, void());
62+
MOCK_METHOD(void, setHwcCompositionType,
63+
(aidl::android::hardware::graphics::composer3::Composition), (override));
64+
MOCK_METHOD(aidl::android::hardware::graphics::composer3::Composition, getHwcCompositionType,
65+
(), (const, override));
6266
};
6367

6468
} // namespace android::compositionengine::mock

services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,7 @@ void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
867867
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
868868
(outputDependentState.hwc->layerSkipped && !skipLayer)) {
869869
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
870+
getLayerFE().setHwcCompositionType(requestedCompositionType);
870871

871872
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
872873
error != hal::Error::NONE) {
@@ -964,6 +965,7 @@ void OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType)
964965
}
965966

966967
hwcState.hwcCompositionType = compositionType;
968+
getLayerFE().setHwcCompositionType(compositionType);
967969
}
968970

969971
void OutputLayer::prepareForDeviceLayerRequests() {

services/surfaceflinger/FrontEnd/LayerSnapshot.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@
1818
#undef LOG_TAG
1919
#define LOG_TAG "SurfaceFlinger"
2020

21-
#include "LayerSnapshot.h"
21+
#include <PowerAdvisor/Workload.h>
22+
#include <aidl/android/hardware/graphics/composer3/Composition.h>
23+
#include <gui/LayerState.h>
24+
2225
#include "Layer.h"
26+
#include "LayerSnapshot.h"
2327

2428
namespace android::surfaceflinger::frontend {
2529

2630
using namespace ftl::flag_operators;
31+
using namespace aidl::android::hardware::graphics::composer3;
2732

2833
namespace {
2934

@@ -532,4 +537,49 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate
532537
}
533538
}
534539

540+
char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) const {
541+
if (!isVisible) {
542+
return '.';
543+
}
544+
545+
switch (compositionType) {
546+
case Composition::INVALID:
547+
return 'i';
548+
case Composition::SOLID_COLOR:
549+
return 'c';
550+
case Composition::CURSOR:
551+
return 'u';
552+
case Composition::SIDEBAND:
553+
return 'd';
554+
case Composition::DISPLAY_DECORATION:
555+
return 'a';
556+
case Composition::REFRESH_RATE_INDICATOR:
557+
return 'r';
558+
case Composition::CLIENT:
559+
case Composition::DEVICE:
560+
break;
561+
}
562+
563+
char code = '.'; // Default to invisible
564+
if (hasBufferOrSidebandStream()) {
565+
code = 'b';
566+
} else if (fillsColor()) {
567+
code = 'c'; // Solid color
568+
} else if (hasBlur()) {
569+
code = 'l'; // Blur
570+
} else if (hasProtectedContent) {
571+
code = 'p'; // Protected content
572+
} else if (drawShadows()) {
573+
code = 's'; // Shadow
574+
} else if (roundedCorner.hasRoundedCorners()) {
575+
code = 'r'; // Rounded corners
576+
}
577+
578+
if (compositionType == Composition::CLIENT) {
579+
return static_cast<char>(std::toupper(code));
580+
} else {
581+
return code;
582+
}
583+
}
584+
535585
} // namespace android::surfaceflinger::frontend

services/surfaceflinger/FrontEnd/LayerSnapshot.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#pragma once
1818

19+
#include <PowerAdvisor/Workload.h>
1920
#include <compositionengine/LayerFECompositionState.h>
2021
#include <renderengine/LayerSettings.h>
2122
#include "DisplayHardware/ComposerHal.h"
@@ -159,6 +160,10 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
159160
friend std::ostream& operator<<(std::ostream& os, const LayerSnapshot& obj);
160161
void merge(const RequestedLayerState& requested, bool forceUpdate, bool displayChanges,
161162
bool forceFullDamage, uint32_t displayRotationFlags);
163+
// Returns a char summarizing the composition request
164+
// This function tries to maintain parity with planner::Plan chars.
165+
char classifyCompositionForDebug(
166+
aidl::android::hardware::graphics::composer3::Composition compositionType) const;
162167
};
163168

164169
} // namespace android::surfaceflinger::frontend

services/surfaceflinger/LayerFE.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,14 @@ ftl::Future<FenceResult> LayerFE::createReleaseFenceFuture() {
427427
LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() {
428428
return mReleaseFencePromiseStatus;
429429
}
430+
431+
void LayerFE::setHwcCompositionType(
432+
aidl::android::hardware::graphics::composer3::Composition type) {
433+
mLastHwcCompositionType = type;
434+
}
435+
436+
aidl::android::hardware::graphics::composer3::Composition LayerFE::getHwcCompositionType() const {
437+
return mLastHwcCompositionType;
438+
}
439+
430440
} // namespace android

services/surfaceflinger/LayerFE.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class LayerFE : public virtual RefBase, public virtual compositionengine::LayerF
5959
void setReleaseFence(const FenceResult& releaseFence) override;
6060
LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override;
6161
void onPictureProfileCommitted() override;
62+
void setHwcCompositionType(aidl::android::hardware::graphics::composer3::Composition) override;
63+
aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
64+
const override;
6265

6366
std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot;
6467

@@ -90,6 +93,8 @@ class LayerFE : public virtual RefBase, public virtual compositionengine::LayerF
9093
std::string mName;
9194
std::promise<FenceResult> mReleaseFence;
9295
ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED;
96+
aidl::android::hardware::graphics::composer3::Composition mLastHwcCompositionType =
97+
aidl::android::hardware::graphics::composer3::Composition::INVALID;
9398
};
9499

95100
} // namespace android

services/surfaceflinger/PowerAdvisor/PowerAdvisor.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929

3030
#include <android-base/properties.h>
3131
#include <android/binder_libbinder.h>
32+
#include <common/WorkloadTracer.h>
3233
#include <common/trace.h>
34+
#include <ftl/concat.h>
3335
#include <utils/Log.h>
3436
#include <utils/Mutex.h>
3537

@@ -44,6 +46,7 @@
4446

4547
namespace android::adpf::impl {
4648

49+
using namespace android::ftl::flag_operators;
4750
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
4851
using android::hardware::EventFlag;
4952

@@ -62,6 +65,8 @@ void traceExpensiveRendering(bool enabled) {
6265
}
6366
}
6467

68+
static constexpr ftl::Flags<Workload> TRIGGER_LOAD_CHANGE_HINTS = Workload::EFFECTS |
69+
Workload::VISIBLE_REGION | Workload::DISPLAY_CHANGES | Workload::SCREENSHOT;
6570
} // namespace
6671

6772
PowerAdvisor::PowerAdvisor(std::function<void()>&& sfDisableExpensiveFn,
@@ -756,4 +761,58 @@ power::PowerHalController& PowerAdvisor::getPowerHal() {
756761
return *mPowerHal;
757762
}
758763

764+
void PowerAdvisor::setQueuedWorkload(ftl::Flags<Workload> queued) {
765+
queued &= TRIGGER_LOAD_CHANGE_HINTS;
766+
if (!(queued).get()) return;
767+
uint32_t previousQueuedWorkload = mQueuedWorkload.fetch_or(queued.get());
768+
769+
uint32_t newHints = (previousQueuedWorkload ^ queued.get()) & queued.get();
770+
if (newHints) {
771+
SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
772+
ftl::Concat("QueuedWorkload: ",
773+
ftl::truncated<20>(ftl::Flags<Workload>(newHints)
774+
.string()
775+
.c_str()))
776+
.c_str());
777+
}
778+
if (!previousQueuedWorkload) {
779+
// TODO(b/385028458) maybe load up hint if close to wake up
780+
}
781+
}
782+
783+
void PowerAdvisor::setScreenshotWorkload() {
784+
mCommittedWorkload |= Workload::SCREENSHOT;
785+
}
786+
787+
void PowerAdvisor::setCommittedWorkload(ftl::Flags<Workload> workload) {
788+
workload &= TRIGGER_LOAD_CHANGE_HINTS;
789+
uint32_t queued = mQueuedWorkload.exchange(0);
790+
mCommittedWorkload |= workload;
791+
792+
bool cancelLoadupHint = queued && !mCommittedWorkload.get();
793+
if (cancelLoadupHint) {
794+
SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
795+
ftl::Concat("UncommittedQueuedWorkload: ",
796+
ftl::truncated<20>(ftl::Flags<Workload>(queued)
797+
.string()
798+
.c_str()))
799+
.c_str());
800+
// TODO(b/385028458) cancel load up hint
801+
}
802+
803+
bool increasedWorkload = queued == 0 && mCommittedWorkload.get() != 0;
804+
if (increasedWorkload) {
805+
SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
806+
ftl::Concat("CommittedWorkload: ",
807+
ftl::truncated<20>(mCommittedWorkload.string()))
808+
.c_str());
809+
810+
// TODO(b/385028458) load up hint
811+
}
812+
}
813+
814+
void PowerAdvisor::setCompositedWorkload(ftl::Flags<Workload> composited) {
815+
composited &= TRIGGER_LOAD_CHANGE_HINTS;
816+
mCommittedWorkload = composited;
817+
}
759818
} // namespace android::adpf::impl

services/surfaceflinger/PowerAdvisor/PowerAdvisor.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
#include <fmq/AidlMessageQueue.h>
3333
#pragma clang diagnostic pop
3434

35+
#include <common/trace.h>
36+
#include <ftl/flags.h>
3537
#include <scheduler/Time.h>
3638
#include <ui/DisplayIdentification.h>
3739
#include "../Scheduler/OneShotTimer.h"
40+
#include "Workload.h"
3841

3942
#include "SessionManager.h"
4043

@@ -109,6 +112,26 @@ class PowerAdvisor {
109112
// Get the session manager, if it exists
110113
virtual std::shared_ptr<SessionManager> getSessionManager() = 0;
111114

115+
// --- Track per frame workloads to use for load up hint heuristics
116+
// Track queued workload from transactions as they are queued from the binder thread.
117+
// The workload is accumulated and reset on frame commit. The queued workload may be
118+
// relevant for the next frame so can be used as an early load up hint. Note this is
119+
// only a hint because the transaction can remain in the queue and not be applied on
120+
// the next frame.
121+
virtual void setQueuedWorkload(ftl::Flags<Workload> workload) = 0;
122+
// Track additional workload dur to a screenshot request for load up hint heuristics. This
123+
// would indicate an immediate increase in GPU workload.
124+
virtual void setScreenshotWorkload() = 0;
125+
// Track committed workload from transactions that are applied on the main thread.
126+
// This workload is determined from the applied transactions. This can provide a high
127+
// confidence that the CPU and or GPU workload will increase immediately.
128+
virtual void setCommittedWorkload(ftl::Flags<Workload> workload) = 0;
129+
// Update committed workload with the actual workload from post composition. This is
130+
// used to update the baseline workload so we can detect increases in workloads on the
131+
// next commit. We use composite instead of commit to update the baseline to account
132+
// for optimizations like caching which may reduce the workload.
133+
virtual void setCompositedWorkload(ftl::Flags<Workload> workload) = 0;
134+
112135
// --- The following methods may run on threads besides SF main ---
113136
// Send a hint about an upcoming increase in the CPU workload
114137
virtual void notifyCpuLoadUp() = 0;
@@ -158,6 +181,11 @@ class PowerAdvisor final : public adpf::PowerAdvisor {
158181
void setTotalFrameTargetWorkDuration(Duration targetDuration) override;
159182
std::shared_ptr<SessionManager> getSessionManager() override;
160183

184+
void setQueuedWorkload(ftl::Flags<Workload> workload) override;
185+
void setScreenshotWorkload() override;
186+
void setCommittedWorkload(ftl::Flags<Workload> workload) override;
187+
void setCompositedWorkload(ftl::Flags<Workload> workload) override;
188+
161189
// --- The following methods may run on threads besides SF main ---
162190
void notifyCpuLoadUp() override;
163191
void notifyDisplayUpdateImminentAndCpuReset() override;
@@ -332,6 +360,11 @@ class PowerAdvisor final : public adpf::PowerAdvisor {
332360
static constexpr const Duration kFenceWaitStartDelayValidated{150us};
333361
static constexpr const Duration kFenceWaitStartDelaySkippedValidate{250us};
334362

363+
// Track queued and committed workloads per frame. Queued workload is atomic because it's
364+
// updated on both binder and the main thread.
365+
std::atomic<uint32_t> mQueuedWorkload;
366+
ftl::Flags<Workload> mCommittedWorkload;
367+
335368
void sendHintSessionHint(aidl::android::hardware::power::SessionHint hint);
336369

337370
template <aidl::android::hardware::power::ChannelMessage::ChannelMessageContents::Tag T,

0 commit comments

Comments
 (0)