diff options
author | 2021-09-26 17:27:01 -0700 | |
---|---|---|
committer | 2021-11-19 12:53:03 -0800 | |
commit | f5d0ea545aaea01d8d73ad97603619ec3874a2e7 (patch) | |
tree | cd44326adcfa54fe0292c9279e40720b4f9d3c34 | |
parent | 079ec332de6012a59a4bfa4ed9ba967189e0f4da (diff) |
SF: Remove manual enum stringification
Upgrade to scoped enums where applicable. Pull GameMode from TimeStats
into libgui to plumb it as an enum rather than int32_t.
Bug: 185536303
Test: libsurfaceflinger_unittest
Change-Id: I81fdd24805757ef953484055ee867684eb94fecf
29 files changed, 346 insertions, 485 deletions
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h index de14b3d785..27f4d379e9 100644 --- a/libs/gui/include/gui/LayerMetadata.h +++ b/libs/gui/include/gui/LayerMetadata.h @@ -59,4 +59,14 @@ struct LayerMetadata : public Parcelable { std::string itemToString(uint32_t key, const char* separator) const; }; +// Keep in sync with the GameManager.java constants. +enum class GameMode : int32_t { + Unsupported = 0, + Standard = 1, + Performance = 2, + Battery = 3, + + ftl_last = Battery +}; + } // namespace android diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 861d4963f7..490775faec 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -401,12 +401,13 @@ void BufferLayer::onPostComposition(const DisplayDevice* display, const Fps refreshRate = display->refreshRateConfigs().getCurrentRefreshRate().getFps(); const std::optional<Fps> renderRate = mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); + + const auto vote = frameRateToSetFrameRateVotePayload(mDrawingState.frameRate); + const auto gameMode = getGameMode(); + if (presentFence->isValid()) { mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence, - refreshRate, renderRate, - frameRateToSetFrameRateVotePayload( - mDrawingState.frameRate), - getGameMode()); + refreshRate, renderRate, vote, gameMode); mFlinger->mFrameTracer->traceFence(layerId, getCurrentBufferId(), mCurrentFrameNumber, presentFence, FrameTracer::FrameEvent::PRESENT_FENCE); @@ -417,10 +418,7 @@ void BufferLayer::onPostComposition(const DisplayDevice* display, // timestamp instead. const nsecs_t actualPresentTime = display->getRefreshTimestamp(); mFlinger->mTimeStats->setPresentTime(layerId, mCurrentFrameNumber, actualPresentTime, - refreshRate, renderRate, - frameRateToSetFrameRateVotePayload( - mDrawingState.frameRate), - getGameMode()); + refreshRate, renderRate, vote, gameMode); mFlinger->mFrameTracer->traceTimestamp(layerId, getCurrentBufferId(), mCurrentFrameNumber, actualPresentTime, FrameTracer::FrameEvent::PRESENT_FENCE); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h index 4502eee97c..c553fce85d 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplaySurface.h @@ -16,6 +16,8 @@ #pragma once +#include <cinttypes> + #include <ui/Size.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -47,13 +49,8 @@ public: // before composition takes place. The DisplaySurface can use the // composition type to decide how to manage the flow of buffers between // GPU and HWC for this frame. - enum CompositionType { - COMPOSITION_UNKNOWN = 0, - COMPOSITION_GPU = 1, - COMPOSITION_HWC = 2, - COMPOSITION_MIXED = COMPOSITION_GPU | COMPOSITION_HWC - }; - virtual status_t prepareFrame(CompositionType compositionType) = 0; + enum class CompositionType : uint8_t { Unknown = 0, Gpu = 0b1, Hwc = 0b10, Mixed = Gpu | Hwc }; + virtual status_t prepareFrame(CompositionType) = 0; // Inform the surface that GPU composition is complete for this frame, and // the surface should make sure that HWComposer has the correct buffer for diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp index ef50870615..a19d23febf 100644 --- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp +++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp @@ -127,19 +127,18 @@ status_t RenderSurface::beginFrame(bool mustRecompose) { } void RenderSurface::prepareFrame(bool usesClientComposition, bool usesDeviceComposition) { - DisplaySurface::CompositionType compositionType; - if (usesClientComposition && usesDeviceComposition) { - compositionType = DisplaySurface::COMPOSITION_MIXED; - } else if (usesClientComposition) { - compositionType = DisplaySurface::COMPOSITION_GPU; - } else if (usesDeviceComposition) { - compositionType = DisplaySurface::COMPOSITION_HWC; - } else { + const auto compositionType = [=] { + using CompositionType = DisplaySurface::CompositionType; + + if (usesClientComposition && usesDeviceComposition) return CompositionType::Mixed; + if (usesClientComposition) return CompositionType::Gpu; + if (usesDeviceComposition) return CompositionType::Hwc; + // Nothing to do -- when turning the screen off we get a frame like // this. Call it a HWC frame since we won't be doing any GPU work but // will do a prepare/set cycle. - compositionType = DisplaySurface::COMPOSITION_HWC; - } + return CompositionType::Hwc; + }(); if (status_t result = mDisplaySurface->prepareFrame(compositionType); result != NO_ERROR) { ALOGE("updateCompositionType failed for %s: %d (%s)", mDisplay.getName().c_str(), result, diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp index 431cc93514..7c8e41b53e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp @@ -201,28 +201,28 @@ TEST_F(RenderSurfaceTest, beginFrameAppliesChange) { */ TEST_F(RenderSurfaceTest, prepareFrameHandlesMixedComposition) { - EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_MIXED)) + EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Mixed)) .WillOnce(Return(NO_ERROR)); mSurface.prepareFrame(true, true); } TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyGpuComposition) { - EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_GPU)) + EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Gpu)) .WillOnce(Return(NO_ERROR)); mSurface.prepareFrame(true, false); } TEST_F(RenderSurfaceTest, prepareFrameHandlesOnlyHwcComposition) { - EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)) + EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Hwc)) .WillOnce(Return(NO_ERROR)); mSurface.prepareFrame(false, true); } TEST_F(RenderSurfaceTest, prepareFrameHandlesNoComposition) { - EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)) + EXPECT_CALL(*mDisplaySurface, prepareFrame(DisplaySurface::CompositionType::Hwc)) .WillOnce(Return(NO_ERROR)); mSurface.prepareFrame(false, false); diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 82a9ae2578..b4fb51f9d5 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -21,20 +21,18 @@ // #define LOG_NDEBUG 0 #include "VirtualDisplaySurface.h" -#include <inttypes.h> +#include <cinttypes> #include "HWComposer.h" #include "SurfaceFlinger.h" +#include <ftl/Flags.h> +#include <ftl/enum.h> #include <gui/BufferItem.h> #include <gui/BufferQueue.h> #include <gui/IProducerListener.h> #include <system/window.h> -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - #define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \ mDisplayName.c_str(), ##__VA_ARGS__) #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \ @@ -42,20 +40,11 @@ namespace android { #define VDS_LOGV(msg, ...) ALOGV("[%s] " msg, \ mDisplayName.c_str(), ##__VA_ARGS__) -static const char* dbgCompositionTypeStr(compositionengine::DisplaySurface::CompositionType type) { - switch (type) { - case compositionengine::DisplaySurface::COMPOSITION_UNKNOWN: - return "UNKNOWN"; - case compositionengine::DisplaySurface::COMPOSITION_GPU: - return "GPU"; - case compositionengine::DisplaySurface::COMPOSITION_HWC: - return "HWC"; - case compositionengine::DisplaySurface::COMPOSITION_MIXED: - return "MIXED"; - default: - return "<INVALID>"; - } -} +#define UNSUPPORTED() \ + VDS_LOGE("%s: Invalid operation on virtual display", __func__); \ + return INVALID_OPERATION + +namespace android { VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId, const sp<IGraphicBufferProducer>& sink, @@ -76,14 +65,10 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId d mQueueBufferOutput(), mSinkBufferWidth(0), mSinkBufferHeight(0), - mCompositionType(COMPOSITION_UNKNOWN), mFbFence(Fence::NO_FENCE), mOutputFence(Fence::NO_FENCE), mFbProducerSlot(BufferQueue::INVALID_BUFFER_SLOT), mOutputProducerSlot(BufferQueue::INVALID_BUFFER_SLOT), - mDbgState(DBG_STATE_IDLE), - mDbgLastCompositionType(COMPOSITION_UNKNOWN), - mMustRecompose(false), mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv) { mSource[SOURCE_SINK] = sink; mSource[SOURCE_SCRATCH] = bqProducer; @@ -131,9 +116,9 @@ status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) { mMustRecompose = mustRecompose; - VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE, - "Unexpected beginFrame() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_BEGUN; + VDS_LOGW_IF(mDebugState != DebugState::Idle, "Unexpected %s in %s state", __func__, + ftl::enum_string(mDebugState).c_str()); + mDebugState = DebugState::Begun; return refreshOutputBuffer(); } @@ -143,12 +128,12 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { return NO_ERROR; } - VDS_LOGW_IF(mDbgState != DBG_STATE_BEGUN, - "Unexpected prepareFrame() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_PREPARED; + VDS_LOGW_IF(mDebugState != DebugState::Begun, "Unexpected %s in %s state", __func__, + ftl::enum_string(mDebugState).c_str()); + mDebugState = DebugState::Prepared; mCompositionType = compositionType; - if (mForceHwcCopy && mCompositionType == COMPOSITION_GPU) { + if (mForceHwcCopy && mCompositionType == CompositionType::Gpu) { // Some hardware can do RGB->YUV conversion more efficiently in hardware // controlled by HWC than in hardware controlled by the video encoder. // Forcing GPU-composed frames to go through an extra copy by the HWC @@ -157,16 +142,16 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { // // On the other hand, when the consumer prefers RGB or can consume RGB // inexpensively, this forces an unnecessary copy. - mCompositionType = COMPOSITION_MIXED; + mCompositionType = CompositionType::Mixed; } - if (mCompositionType != mDbgLastCompositionType) { - VDS_LOGV("prepareFrame: composition type changed to %s", - dbgCompositionTypeStr(mCompositionType)); - mDbgLastCompositionType = mCompositionType; + if (mCompositionType != mDebugLastCompositionType) { + VDS_LOGV("%s: composition type changed to %s", __func__, + toString(mCompositionType).c_str()); + mDebugLastCompositionType = mCompositionType; } - if (mCompositionType != COMPOSITION_GPU && + if (mCompositionType != CompositionType::Gpu && (mOutputFormat != mDefaultOutputFormat || mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) { // We must have just switched from GPU-only to MIXED or HWC // composition. Stop using the format and usage requested by the GPU @@ -191,33 +176,32 @@ status_t VirtualDisplaySurface::advanceFrame() { return NO_ERROR; } - if (mCompositionType == COMPOSITION_HWC) { - VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, - "Unexpected advanceFrame() in %s state on HWC frame", - dbgStateStr()); + if (mCompositionType == CompositionType::Hwc) { + VDS_LOGW_IF(mDebugState != DebugState::Prepared, "Unexpected %s in %s state on HWC frame", + __func__, ftl::enum_string(mDebugState).c_str()); } else { - VDS_LOGW_IF(mDbgState != DBG_STATE_GPU_DONE, - "Unexpected advanceFrame() in %s state on GPU/MIXED frame", dbgStateStr()); + VDS_LOGW_IF(mDebugState != DebugState::GpuDone, + "Unexpected %s in %s state on GPU/MIXED frame", __func__, + ftl::enum_string(mDebugState).c_str()); } - mDbgState = DBG_STATE_HWC; + mDebugState = DebugState::Hwc; if (mOutputProducerSlot < 0 || - (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 0)) { + (mCompositionType != CompositionType::Hwc && mFbProducerSlot < 0)) { // Last chance bailout if something bad happened earlier. For example, // in a graphics API configuration, if the sink disappears then dequeueBuffer // will fail, the GPU driver won't queue a buffer, but SurfaceFlinger // will soldier on. So we end up here without a buffer. There should // be lots of scary messages in the log just before this. - VDS_LOGE("advanceFrame: no buffer, bailing out"); + VDS_LOGE("%s: no buffer, bailing out", __func__); return NO_MEMORY; } sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ? mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(nullptr); sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot]; - VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)", - mFbProducerSlot, fbBuffer.get(), - mOutputProducerSlot, outBuffer.get()); + VDS_LOGV("%s: fb=%d(%p) out=%d(%p)", __func__, mFbProducerSlot, fbBuffer.get(), + mOutputProducerSlot, outBuffer.get()); const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId); LOG_FATAL_IF(!halDisplayId); @@ -245,16 +229,16 @@ void VirtualDisplaySurface::onFrameCommitted() { return; } - VDS_LOGW_IF(mDbgState != DBG_STATE_HWC, - "Unexpected onFrameCommitted() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_IDLE; + VDS_LOGW_IF(mDebugState != DebugState::Hwc, "Unexpected %s in %s state", __func__, + ftl::enum_string(mDebugState).c_str()); + mDebugState = DebugState::Idle; sp<Fence> retireFence = mHwc.getPresentFence(*halDisplayId); - if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) { + if (mCompositionType == CompositionType::Mixed && mFbProducerSlot >= 0) { // release the scratch buffer back to the pool Mutex::Autolock lock(mMutex); int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot); - VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot); + VDS_LOGV("%s: release scratch sslot=%d", __func__, sslot); addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], retireFence); releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot]); @@ -263,7 +247,7 @@ void VirtualDisplaySurface::onFrameCommitted() { if (mOutputProducerSlot >= 0) { int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot); QueueBufferOutput qbo; - VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot); + VDS_LOGV("%s: queue sink sslot=%d", __func__, sslot); if (mMustRecompose) { status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, QueueBufferInput( @@ -308,8 +292,8 @@ status_t VirtualDisplaySurface::requestBuffer(int pslot, return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf); } - VDS_LOGW_IF(mDbgState != DBG_STATE_GPU, "Unexpected requestBuffer pslot=%d in %s state", pslot, - dbgStateStr()); + VDS_LOGW_IF(mDebugState != DebugState::Gpu, "Unexpected %s pslot=%d in %s state", __func__, + pslot, ftl::enum_string(mDebugState).c_str()); *outBuf = mProducerBuffers[pslot]; return NO_ERROR; @@ -334,8 +318,8 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, if (result < 0) return result; int pslot = mapSource2ProducerSlot(source, *sslot); - VDS_LOGV("dequeueBuffer(%s): sslot=%d pslot=%d result=%d", - dbgSourceStr(source), *sslot, pslot, result); + VDS_LOGV("%s(%s): sslot=%d pslot=%d result=%d", __func__, ftl::enum_string(source).c_str(), + *sslot, pslot, result); uint64_t sourceBit = static_cast<uint64_t>(source) << pslot; // reset producer slot reallocation flag @@ -363,10 +347,9 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source, mSource[source]->cancelBuffer(*sslot, *fence); return result; } - VDS_LOGV("dequeueBuffer(%s): buffers[%d]=%p fmt=%d usage=%#" PRIx64, - dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(), - mProducerBuffers[pslot]->getPixelFormat(), - mProducerBuffers[pslot]->getUsage()); + VDS_LOGV("%s(%s): buffers[%d]=%p fmt=%d usage=%#" PRIx64, __func__, + ftl::enum_string(source).c_str(), pslot, mProducerBuffers[pslot].get(), + mProducerBuffers[pslot]->getPixelFormat(), mProducerBuffers[pslot]->getUsage()); // propagate reallocation to VDS consumer mProducerSlotNeedReallocation |= 1ULL << pslot; @@ -384,11 +367,11 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint outTimestamps); } - VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, - "Unexpected dequeueBuffer() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_GPU; + VDS_LOGW_IF(mDebugState != DebugState::Prepared, "Unexpected %s in %s state", __func__, + ftl::enum_string(mDebugState).c_str()); + mDebugState = DebugState::Gpu; - VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#" PRIx64, w, h, format, usage); + VDS_LOGV("%s %dx%d fmt=%d usage=%#" PRIx64, __func__, w, h, format, usage); status_t result = NO_ERROR; Source source = fbSourceForCompositionType(mCompositionType); @@ -401,7 +384,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint // will fail, the GPU driver won't queue a buffer, but SurfaceFlinger // will soldier on. So we end up here without a buffer. There should // be lots of scary messages in the log just before this. - VDS_LOGE("dequeueBuffer: no buffer, bailing out"); + VDS_LOGE("%s: no buffer, bailing out", __func__); return NO_MEMORY; } @@ -417,12 +400,11 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint (format != 0 && format != buf->getPixelFormat()) || (w != 0 && w != mSinkBufferWidth) || (h != 0 && h != mSinkBufferHeight)) { - VDS_LOGV("dequeueBuffer: dequeueing new output buffer: " - "want %dx%d fmt=%d use=%#" PRIx64 ", " - "have %dx%d fmt=%d use=%#" PRIx64, - w, h, format, usage, - mSinkBufferWidth, mSinkBufferHeight, - buf->getPixelFormat(), buf->getUsage()); + VDS_LOGV("%s: dequeueing new output buffer: " + "want %dx%d fmt=%d use=%#" PRIx64 ", " + "have %dx%d fmt=%d use=%#" PRIx64, + __func__, w, h, format, usage, mSinkBufferWidth, mSinkBufferHeight, + buf->getPixelFormat(), buf->getUsage()); mOutputFormat = format; mOutputUsage = usage; result = refreshOutputBuffer(); @@ -452,21 +434,16 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint return result; } -status_t VirtualDisplaySurface::detachBuffer(int /* slot */) { - VDS_LOGE("detachBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::detachBuffer(int) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::detachNextBuffer( - sp<GraphicBuffer>* /* outBuffer */, sp<Fence>* /* outFence */) { - VDS_LOGE("detachNextBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::detachNextBuffer(sp<GraphicBuffer>*, sp<Fence>*) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::attachBuffer(int* /* outSlot */, - const sp<GraphicBuffer>& /* buffer */) { - VDS_LOGE("attachBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::attachBuffer(int*, const sp<GraphicBuffer>&) { + UNSUPPORTED(); } status_t VirtualDisplaySurface::queueBuffer(int pslot, @@ -475,14 +452,14 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output); } - VDS_LOGW_IF(mDbgState != DBG_STATE_GPU, "Unexpected queueBuffer(pslot=%d) in %s state", pslot, - dbgStateStr()); - mDbgState = DBG_STATE_GPU_DONE; + VDS_LOGW_IF(mDebugState != DebugState::Gpu, "Unexpected %s(pslot=%d) in %s state", __func__, + pslot, ftl::enum_string(mDebugState).c_str()); + mDebugState = DebugState::GpuDone; - VDS_LOGV("queueBuffer pslot=%d", pslot); + VDS_LOGV("%s pslot=%d", __func__, pslot); status_t result; - if (mCompositionType == COMPOSITION_MIXED) { + if (mCompositionType == CompositionType::Mixed) { // Queue the buffer back into the scratch pool QueueBufferOutput scratchQBO; int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot); @@ -498,15 +475,15 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot, if (result != NO_ERROR) return result; VDS_LOGW_IF(item.mSlot != sslot, - "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d", - item.mSlot, sslot); + "%s: acquired sslot %d from SCRATCH after queueing sslot %d", __func__, + item.mSlot, sslot); mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mSlot); mFbFence = mSlots[item.mSlot].mFence; } else { - LOG_FATAL_IF(mCompositionType != COMPOSITION_GPU, - "Unexpected queueBuffer in state %s for compositionType %s", dbgStateStr(), - dbgCompositionTypeStr(mCompositionType)); + LOG_FATAL_IF(mCompositionType != CompositionType::Gpu, + "Unexpected %s in state %s for composition type %s", __func__, + ftl::enum_string(mDebugState).c_str(), toString(mCompositionType).c_str()); // Extract the GPU release fence for HWC to acquire int64_t timestamp; @@ -533,9 +510,9 @@ status_t VirtualDisplaySurface::cancelBuffer(int pslot, return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence); } - VDS_LOGW_IF(mDbgState != DBG_STATE_GPU, "Unexpected cancelBuffer(pslot=%d) in %s state", pslot, - dbgStateStr()); - VDS_LOGV("cancelBuffer pslot=%d", pslot); + VDS_LOGW_IF(mDebugState != DebugState::Gpu, "Unexpected %s(pslot=%d) in %s state", __func__, + pslot, ftl::enum_string(mDebugState).c_str()); + VDS_LOGV("%s pslot=%d", __func__, pslot); Source source = fbSourceForCompositionType(mCompositionType); return mSource[source]->cancelBuffer( mapProducer2SourceSlot(source, pslot), fence); @@ -573,8 +550,8 @@ status_t VirtualDisplaySurface::disconnect(int api, DisconnectMode mode) { return mSource[SOURCE_SINK]->disconnect(api, mode); } -status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) { - return INVALID_OPERATION; +status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>&) { + UNSUPPORTED(); } void VirtualDisplaySurface::allocateBuffers(uint32_t /* width */, @@ -586,40 +563,32 @@ status_t VirtualDisplaySurface::allowAllocation(bool /* allow */) { return INVALID_OPERATION; } -status_t VirtualDisplaySurface::setGenerationNumber(uint32_t /* generation */) { - ALOGE("setGenerationNumber not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::setGenerationNumber(uint32_t) { + UNSUPPORTED(); } String8 VirtualDisplaySurface::getConsumerName() const { return String8("VirtualDisplaySurface"); } -status_t VirtualDisplaySurface::setSharedBufferMode(bool /*sharedBufferMode*/) { - ALOGE("setSharedBufferMode not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::setSharedBufferMode(bool) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::setAutoRefresh(bool /*autoRefresh*/) { - ALOGE("setAutoRefresh not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::setAutoRefresh(bool) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::setDequeueTimeout(nsecs_t /* timeout */) { - ALOGE("setDequeueTimeout not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::setDequeueTimeout(nsecs_t) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::getLastQueuedBuffer( - sp<GraphicBuffer>* /*outBuffer*/, sp<Fence>* /*outFence*/, - float[16] /* outTransformMatrix*/) { - ALOGE("getLastQueuedBuffer not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::getLastQueuedBuffer(sp<GraphicBuffer>*, sp<Fence>*, float[16]) { + UNSUPPORTED(); } -status_t VirtualDisplaySurface::getUniqueId(uint64_t* /*outId*/) const { - ALOGE("getUniqueId not supported on VirtualDisplaySurface"); - return INVALID_OPERATION; +status_t VirtualDisplaySurface::getUniqueId(uint64_t*) const { + UNSUPPORTED(); } status_t VirtualDisplaySurface::getConsumerUsage(uint64_t* outUsage) const { @@ -633,7 +602,7 @@ void VirtualDisplaySurface::updateQueueBufferOutput( } void VirtualDisplaySurface::resetPerFrameState() { - mCompositionType = COMPOSITION_UNKNOWN; + mCompositionType = CompositionType::Unknown; mFbFence = Fence::NO_FENCE; mOutputFence = Fence::NO_FENCE; mOutputProducerSlot = -1; @@ -682,39 +651,16 @@ int VirtualDisplaySurface::mapProducer2SourceSlot(Source source, int pslot) { return mapSource2ProducerSlot(source, pslot); } -VirtualDisplaySurface::Source -VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) { - return type == COMPOSITION_MIXED ? SOURCE_SCRATCH : SOURCE_SINK; +auto VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) -> Source { + return type == CompositionType::Mixed ? SOURCE_SCRATCH : SOURCE_SINK; } -const char* VirtualDisplaySurface::dbgStateStr() const { - switch (mDbgState) { - case DBG_STATE_IDLE: - return "IDLE"; - case DBG_STATE_PREPARED: - return "PREPARED"; - case DBG_STATE_GPU: - return "GPU"; - case DBG_STATE_GPU_DONE: - return "GPU_DONE"; - case DBG_STATE_HWC: - return "HWC"; - default: - return "INVALID"; - } -} - -const char* VirtualDisplaySurface::dbgSourceStr(Source s) { - switch (s) { - case SOURCE_SINK: return "SINK"; - case SOURCE_SCRATCH: return "SCRATCH"; - default: return "INVALID"; - } +std::string VirtualDisplaySurface::toString(CompositionType type) { + using namespace std::literals; + return type == CompositionType::Unknown ? "Unknown"s : Flags(type).string(); } -// --------------------------------------------------------------------------- } // namespace android -// --------------------------------------------------------------------------- // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index bbb6306920..77207134b9 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H -#define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H +#pragma once #include <optional> #include <string> @@ -28,9 +27,7 @@ #include "DisplayIdentification.h" -// --------------------------------------------------------------------------- namespace android { -// --------------------------------------------------------------------------- class HWComposer; class IProducerListener; @@ -94,7 +91,13 @@ public: virtual const sp<Fence>& getClientTargetAcquireFence() const override; private: - enum Source {SOURCE_SINK = 0, SOURCE_SCRATCH = 1}; + enum Source : size_t { + SOURCE_SINK = 0, + SOURCE_SCRATCH = 1, + + ftl_first = SOURCE_SINK, + ftl_last = SOURCE_SCRATCH, + }; virtual ~VirtualDisplaySurface(); @@ -133,6 +136,8 @@ private: // Utility methods // static Source fbSourceForCompositionType(CompositionType); + static std::string toString(CompositionType); + status_t dequeueBuffer(Source, PixelFormat, uint64_t usage, int* sslot, sp<Fence>*); void updateQueueBufferOutput(QueueBufferOutput&&); void resetPerFrameState(); @@ -197,7 +202,7 @@ private: // Composition type and graphics buffer source for the current frame. // Valid after prepareFrame(), cleared in onFrameCommitted. - CompositionType mCompositionType; + CompositionType mCompositionType = CompositionType::Unknown; // mFbFence is the fence HWC should wait for before reading the framebuffer // target buffer. @@ -219,47 +224,42 @@ private: // +-----------+-------------------+-------------+ // | State | Event || Next State | // +-----------+-------------------+-------------+ - // | IDLE | beginFrame || BEGUN | - // | BEGUN | prepareFrame || PREPARED | - // | PREPARED | dequeueBuffer [1] || GPU | - // | PREPARED | advanceFrame [2] || HWC | - // | GPU | queueBuffer || GPU_DONE | - // | GPU_DONE | advanceFrame || HWC | - // | HWC | onFrameCommitted || IDLE | + // | Idle | beginFrame || Begun | + // | Begun | prepareFrame || Prepared | + // | Prepared | dequeueBuffer [1] || Gpu | + // | Prepared | advanceFrame [2] || Hwc | + // | Gpu | queueBuffer || GpuDone | + // | GpuDone | advanceFrame || Hwc | + // | Hwc | onFrameCommitted || Idle | // +-----------+-------------------++------------+ - // [1] COMPOSITION_GPU and COMPOSITION_MIXED frames. - // [2] COMPOSITION_HWC frames. + // [1] CompositionType::Gpu and CompositionType::Mixed frames. + // [2] CompositionType::Hwc frames. // - enum DbgState { + enum class DebugState { // no buffer dequeued, don't know anything about the next frame - DBG_STATE_IDLE, + Idle, // output buffer dequeued, framebuffer source not yet known - DBG_STATE_BEGUN, + Begun, // output buffer dequeued, framebuffer source known but not provided // to GPU yet. - DBG_STATE_PREPARED, + Prepared, // GPU driver has a buffer dequeued - DBG_STATE_GPU, + Gpu, // GPU driver has queued the buffer, we haven't sent it to HWC yet - DBG_STATE_GPU_DONE, + GpuDone, // HWC has the buffer for this frame - DBG_STATE_HWC, - }; - DbgState mDbgState; - CompositionType mDbgLastCompositionType; + Hwc, - const char* dbgStateStr() const; - static const char* dbgSourceStr(Source s); + ftl_last = Hwc + }; + DebugState mDebugState = DebugState::Idle; + CompositionType mDebugLastCompositionType = CompositionType::Unknown; - bool mMustRecompose; + bool mMustRecompose = false; compositionengine::impl::HwcBufferCache mHwcBufferCache; bool mForceHwcCopy; }; -// --------------------------------------------------------------------------- } // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index c294ff2695..0c4e1120fc 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -304,7 +304,7 @@ SurfaceFrame::SurfaceFrame(const FrameTimelineInfo& frameTimelineInfo, pid_t own frametimeline::TimelineItem&& predictions, std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds, - TraceCookieCounter* traceCookieCounter, bool isBuffer, int32_t gameMode) + TraceCookieCounter* traceCookieCounter, bool isBuffer, GameMode gameMode) : mToken(frameTimelineInfo.vsyncId), mInputEventId(frameTimelineInfo.inputEventId), mOwnerPid(ownerPid), @@ -778,7 +778,7 @@ void FrameTimeline::registerDataSource() { std::shared_ptr<SurfaceFrame> FrameTimeline::createSurfaceFrameForToken( const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, int32_t layerId, - std::string layerName, std::string debugName, bool isBuffer, int32_t gameMode) { + std::string layerName, std::string debugName, bool isBuffer, GameMode gameMode) { ATRACE_CALL(); if (frameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { return std::make_shared<SurfaceFrame>(frameTimelineInfo, ownerPid, ownerUid, layerId, diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h index d08344ef6e..36d629077d 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h @@ -26,6 +26,7 @@ #include <gui/ISurfaceComposer.h> #include <gui/JankInfo.h> +#include <gui/LayerMetadata.h> #include <perfetto/trace/android/frame_timeline_event.pbzero.h> #include <perfetto/tracing.h> #include <ui/FenceTime.h> @@ -161,7 +162,7 @@ public: int32_t layerId, std::string layerName, std::string debugName, PredictionState predictionState, TimelineItem&& predictions, std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds, - TraceCookieCounter* traceCookieCounter, bool isBuffer, int32_t gameMode); + TraceCookieCounter* traceCookieCounter, bool isBuffer, GameMode); ~SurfaceFrame() = default; // Returns std::nullopt if the frame hasn't been classified yet. @@ -267,7 +268,7 @@ private: // buffer(animations) bool mIsBuffer; // GameMode from the layer. Used in metrics. - int32_t mGameMode = 0; + GameMode mGameMode = GameMode::Unsupported; }; /* @@ -288,7 +289,7 @@ public: virtual std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken( const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, int32_t layerId, std::string layerName, std::string debugName, bool isBuffer, - int32_t gameMode) = 0; + GameMode) = 0; // Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be // composited into one display frame. @@ -448,7 +449,7 @@ public: std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken( const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, int32_t layerId, std::string layerName, std::string debugName, bool isBuffer, - int32_t gameMode) override; + GameMode) override; void addSurfaceFrame(std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame) override; void setSfWakeUp(int64_t token, nsecs_t wakeupTime, Fps refreshRate) override; void setSfPresent(nsecs_t sfPresentTime, const std::shared_ptr<FenceTime>& presentFence, diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 968a49d526..67f9a92385 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -36,6 +36,7 @@ #include <cutils/compiler.h> #include <cutils/native_handle.h> #include <cutils/properties.h> +#include <ftl/enum.h> #include <gui/BufferItem.h> #include <gui/LayerDebugInfo.h> #include <gui/Surface.h> @@ -1411,19 +1412,6 @@ void Layer::miniDumpHeader(std::string& result) { result.append("\n"); } -std::string Layer::frameRateCompatibilityString(Layer::FrameRateCompatibility compatibility) { - switch (compatibility) { - case FrameRateCompatibility::Default: - return "Default"; - case FrameRateCompatibility::ExactOrMultiple: - return "ExactOrMultiple"; - case FrameRateCompatibility::NoVote: - return "NoVote"; - case FrameRateCompatibility::Exact: - return "Exact"; - } -} - void Layer::miniDump(std::string& result, const DisplayDevice& display) const { const auto outputLayer = findOutputLayerForDisplay(&display); if (!outputLayer) { @@ -1462,8 +1450,8 @@ void Layer::miniDump(std::string& result, const DisplayDevice& display) const { const auto frameRate = getFrameRateForLayerTree(); if (frameRate.rate.isValid() || frameRate.type != FrameRateCompatibility::Default) { StringAppendF(&result, "%s %15s %17s", to_string(frameRate.rate).c_str(), - frameRateCompatibilityString(frameRate.type).c_str(), - toString(frameRate.seamlessness).c_str()); + ftl::enum_string(frameRate.type).c_str(), + ftl::enum_string(frameRate.seamlessness).c_str()); } else { result.append(41, ' '); } @@ -1546,11 +1534,10 @@ size_t Layer::getChildrenCount() const { return count; } -void Layer::setGameModeForTree(int parentGameMode) { - int gameMode = parentGameMode; - auto& currentState = getDrawingState(); +void Layer::setGameModeForTree(GameMode gameMode) { + const auto& currentState = getDrawingState(); if (currentState.metadata.has(METADATA_GAME_MODE)) { - gameMode = currentState.metadata.getInt32(METADATA_GAME_MODE, 0); + gameMode = static_cast<GameMode>(currentState.metadata.getInt32(METADATA_GAME_MODE, 0)); } setGameMode(gameMode); for (const sp<Layer>& child : mCurrentChildren) { @@ -1576,7 +1563,7 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); - layer->setGameModeForTree(0); + layer->setGameModeForTree(GameMode::Unsupported); layer->updateTreeHasFrameRateVote(); return removeResult; @@ -2631,12 +2618,11 @@ bool Layer::setDropInputMode(gui::DropInputMode mode) { // --------------------------------------------------------------------------- std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) { - return stream << "{rate=" << rate.rate - << " type=" << Layer::frameRateCompatibilityString(rate.type) - << " seamlessness=" << toString(rate.seamlessness) << "}"; + return stream << "{rate=" << rate.rate << " type=" << ftl::enum_string(rate.type) + << " seamlessness=" << ftl::enum_string(rate.seamlessness) << '}'; } -}; // namespace android +} // namespace android #if defined(__gl_h_) #error "don't include gl/gl.h in this file" diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 041b439ac7..47885a4f0c 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -328,7 +328,6 @@ public: static bool isLayerFocusedBasedOnPriority(int32_t priority); static void miniDumpHeader(std::string& result); - static std::string frameRateCompatibilityString(FrameRateCompatibility compatibility); // Provide unique string for each class type in the Layer hierarchy virtual const char* getType() const = 0; @@ -854,12 +853,12 @@ public: */ bool hasInputInfo() const; - // Sets the parent's gameMode for this layer and all its children. Parent's gameMode is applied - // only to layers that do not have the GAME_MODE_METADATA set by WMShell. Any layer(along with - // its children) that has the metadata set will use the gameMode from the metadata. - void setGameModeForTree(int32_t parentGameMode); - void setGameMode(int32_t gameMode) { mGameMode = gameMode; }; - int32_t getGameMode() const { return mGameMode; } + // Sets the GameMode for the tree rooted at this layer. A layer in the tree inherits this + // GameMode unless it (or an ancestor) has GAME_MODE_METADATA. + void setGameModeForTree(GameMode); + + void setGameMode(GameMode gameMode) { mGameMode = gameMode; } + GameMode getGameMode() const { return mGameMode; } virtual uid_t getOwnerUid() const { return mOwnerUid; } @@ -1110,9 +1109,8 @@ private: // shadow radius is the set shadow radius, otherwise its the parent's shadow radius. float mEffectiveShadowRadius = 0.f; - // Game mode for the layer. Set by WindowManagerShell, game mode is used in - // metrics(SurfaceFlingerStats). - int32_t mGameMode = 0; + // Game mode for the layer. Set by WindowManagerShell and recorded by SurfaceFlingerStats. + GameMode mGameMode = GameMode::Unsupported; // A list of regions on this layer that should have blurs. const std::vector<BlurRegion> getBlurRegions() const; diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp index 314526a99d..ae61eeb660 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp @@ -28,6 +28,7 @@ #include <cutils/compiler.h> #include <cutils/trace.h> +#include <ftl/enum.h> #undef LOG_TAG #define LOG_TAG "LayerInfo" @@ -257,10 +258,10 @@ LayerInfo::LayerVote LayerInfo::getRefreshRateVote(const RefreshRateConfigs& ref return {LayerHistory::LayerVoteType::Max, Fps()}; } -const char* LayerInfo::getTraceTag(android::scheduler::LayerHistory::LayerVoteType type) const { +const char* LayerInfo::getTraceTag(LayerHistory::LayerVoteType type) const { if (mTraceTags.count(type) == 0) { - const auto tag = "LFPS " + mName + " " + RefreshRateConfigs::layerVoteTypeString(type); - mTraceTags.emplace(type, tag); + auto tag = "LFPS " + mName + " " + ftl::enum_string(type); + mTraceTags.emplace(type, std::move(tag)); } return mTraceTags.at(type).c_str(); diff --git a/services/surfaceflinger/Scheduler/LayerInfo.h b/services/surfaceflinger/Scheduler/LayerInfo.h index 18ed95ec0f..690abda613 100644 --- a/services/surfaceflinger/Scheduler/LayerInfo.h +++ b/services/surfaceflinger/Scheduler/LayerInfo.h @@ -82,6 +82,8 @@ public: NoVote, // Layer doesn't have any requirements for the refresh rate and // should not be considered when the display refresh rate is determined. + + ftl_last = NoVote }; // Encapsulates the frame rate and compatibility of the layer. This information will be used diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index 0d17b0ca94..71d563130e 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -21,23 +21,27 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra" -#include "RefreshRateConfigs.h" +#include <chrono> +#include <cmath> + #include <android-base/properties.h> #include <android-base/stringprintf.h> +#include <ftl/enum.h> #include <utils/Trace.h> -#include <chrono> -#include <cmath> + #include "../SurfaceFlingerProperties.h" +#include "RefreshRateConfigs.h" #undef LOG_TAG #define LOG_TAG "RefreshRateConfigs" namespace android::scheduler { namespace { + std::string formatLayerInfo(const RefreshRateConfigs::LayerRequirement& layer, float weight) { return base::StringPrintf("%s (type=%s, weight=%.2f seamlessness=%s) %s", layer.name.c_str(), - RefreshRateConfigs::layerVoteTypeString(layer.vote).c_str(), weight, - toString(layer.seamlessness).c_str(), + ftl::enum_string(layer.vote).c_str(), weight, + ftl::enum_string(layer.seamlessness).c_str(), to_string(layer.desiredRefreshRate).c_str()); } @@ -74,25 +78,6 @@ std::string RefreshRate::toString() const { mode->getWidth(), mode->getHeight(), getModeGroup()); } -std::string RefreshRateConfigs::layerVoteTypeString(LayerVoteType vote) { - switch (vote) { - case LayerVoteType::NoVote: - return "NoVote"; - case LayerVoteType::Min: - return "Min"; - case LayerVoteType::Max: - return "Max"; - case LayerVoteType::Heuristic: - return "Heuristic"; - case LayerVoteType::ExplicitDefault: - return "ExplicitDefault"; - case LayerVoteType::ExplicitExactOrMultiple: - return "ExplicitExactOrMultiple"; - case LayerVoteType::ExplicitExact: - return "ExplicitExact"; - } -} - std::string RefreshRateConfigs::Policy::toString() const { return base::StringPrintf("default mode ID: %d, allowGroupSwitching = %d" ", primary range: %s, app request range: %s", @@ -405,7 +390,7 @@ RefreshRate RefreshRateConfigs::getBestRefreshRateLocked( for (const auto& layer : layers) { ALOGV("Calculating score for %s (%s, weight %.2f, desired %.2f) ", layer.name.c_str(), - layerVoteTypeString(layer.vote).c_str(), layer.weight, + ftl::enum_string(layer.vote).c_str(), layer.weight, layer.desiredRefreshRate.getValue()); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) { continue; diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h index 8a1c2062a6..8c38083561 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -206,6 +206,7 @@ public: ExplicitExact, // Specific refresh rate that was provided by the app with // Exact compatibility + ftl_last = ExplicitExact }; // Captures the layer requirements for a refresh rate. This will be used to determine the @@ -285,9 +286,6 @@ public: // Stores the current modeId the device operates at void setCurrentModeId(DisplayModeId) EXCLUDES(mLock); - // Returns a string that represents the layer vote type - static std::string layerVoteTypeString(LayerVoteType vote); - // Returns a known frame rate that is the closest to frameRate Fps findClosestKnownFrameRate(Fps frameRate) const; diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp index c9c2d84a2a..22c3a709de 100644 --- a/services/surfaceflinger/Scheduler/Timer.cpp +++ b/services/surfaceflinger/Scheduler/Timer.cpp @@ -17,14 +17,18 @@ #undef LOG_TAG #define LOG_TAG "SchedulerTimer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include <android-base/stringprintf.h> -#include <log/log.h> + +#include <chrono> +#include <cstdint> + #include <sys/epoll.h> #include <sys/timerfd.h> #include <sys/unistd.h> + +#include <android-base/stringprintf.h> +#include <ftl/enum.h> +#include <log/log.h> #include <utils/Trace.h> -#include <chrono> -#include <cstdint> #include "SchedulerUtils.h" #include "Timer.h" @@ -215,26 +219,9 @@ void Timer::setDebugState(DebugState state) { mDebugState = state; } -const char* Timer::strDebugState(DebugState state) const { - switch (state) { - case DebugState::Reset: - return "Reset"; - case DebugState::Running: - return "Running"; - case DebugState::Waiting: - return "Waiting"; - case DebugState::Reading: - return "Reading"; - case DebugState::InCallback: - return "InCallback"; - case DebugState::Terminated: - return "Terminated"; - } -} - void Timer::dump(std::string& result) const { std::lock_guard lock(mMutex); - StringAppendF(&result, "\t\tDebugState: %s\n", strDebugState(mDebugState)); + StringAppendF(&result, "\t\tDebugState: %s\n", ftl::enum_string(mDebugState).c_str()); } } // namespace android::scheduler diff --git a/services/surfaceflinger/Scheduler/Timer.h b/services/surfaceflinger/Scheduler/Timer.h index 69ce079437..628d800bc7 100644 --- a/services/surfaceflinger/Scheduler/Timer.h +++ b/services/surfaceflinger/Scheduler/Timer.h @@ -37,11 +37,20 @@ public: void dump(std::string& result) const final; private: - enum class DebugState { Reset, Running, Waiting, Reading, InCallback, Terminated }; + enum class DebugState { + Reset, + Running, + Waiting, + Reading, + InCallback, + Terminated, + + ftl_last = Terminated + }; + void reset(); void cleanup(); void setDebugState(DebugState state) EXCLUDES(mMutex); - const char* strDebugState(DebugState state) const; int mTimerFd = -1; int mEpollFd = -1; diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h b/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h index d7667ec9c6..93bf726731 100644 --- a/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h +++ b/services/surfaceflinger/Scheduler/include/scheduler/Seamlessness.h @@ -17,7 +17,8 @@ #pragma once #include <ostream> -#include <string> + +#include <ftl/enum.h> namespace android::scheduler { @@ -30,23 +31,14 @@ enum class Seamlessness { // Indicates no preference for seamlessness. For such layers the system will // prefer seamless switches, but also non-seamless switches to the group of the // default config are allowed. - Default -}; + Default, -inline std::string toString(Seamlessness seamlessness) { - switch (seamlessness) { - case Seamlessness::OnlySeamless: - return "OnlySeamless"; - case Seamlessness::SeamedAndSeamless: - return "SeamedAndSeamless"; - case Seamlessness::Default: - return "Default"; - } -} + ftl_last = Default +}; // Used by gtest -inline std::ostream& operator<<(std::ostream& os, Seamlessness val) { - return os << toString(val); +inline std::ostream& operator<<(std::ostream& os, Seamlessness s) { + return os << ftl::enum_string(s); } } // namespace android::scheduler diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e497d95306..0a6eb4ff2a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4158,13 +4158,14 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime std::optional<nsecs_t> dequeueBufferTimestamp; if (what & layer_state_t::eMetadataChanged) { dequeueBufferTimestamp = s.metadata.getInt64(METADATA_DEQUEUE_TIME); - auto gameMode = s.metadata.getInt32(METADATA_GAME_MODE, -1); - if (gameMode != -1) { + + if (const int32_t gameMode = s.metadata.getInt32(METADATA_GAME_MODE, -1); gameMode != -1) { // The transaction will be received on the Task layer and needs to be applied to all // child layers. Child layers that are added at a later point will obtain the game mode // info through addChild(). - layer->setGameModeForTree(gameMode); + layer->setGameModeForTree(static_cast<GameMode>(gameMode)); } + if (layer->setMetadata(s.metadata)) flags |= eTraversalNeeded; } if (what & layer_state_t::eColorSpaceAgnosticChanged) { diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp index bf2038b277..b1a2bdaa91 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.cpp +++ b/services/surfaceflinger/TimeStats/TimeStats.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include <unordered_map> #undef LOG_TAG #define LOG_TAG "TimeStats" #define ATRACE_TAG ATRACE_TAG_GRAPHICS @@ -28,6 +27,7 @@ #include <algorithm> #include <chrono> +#include <unordered_map> #include "TimeStats.h" #include "timestatsproto/TimeStatsHelper.h" @@ -58,15 +58,15 @@ FrameTimingHistogram histogramToProto(const std::unordered_map<int32_t, int32_t> return histogramProto; } -SurfaceflingerStatsLayerInfo_GameMode gameModeToProto(int32_t gameMode) { +SurfaceflingerStatsLayerInfo_GameMode gameModeToProto(GameMode gameMode) { switch (gameMode) { - case TimeStatsHelper::GameModeUnsupported: + case GameMode::Unsupported: return SurfaceflingerStatsLayerInfo::GAME_MODE_UNSUPPORTED; - case TimeStatsHelper::GameModeStandard: + case GameMode::Standard: return SurfaceflingerStatsLayerInfo::GAME_MODE_STANDARD; - case TimeStatsHelper::GameModePerformance: + case GameMode::Performance: return SurfaceflingerStatsLayerInfo::GAME_MODE_PERFORMANCE; - case TimeStatsHelper::GameModeBattery: + case GameMode::Battery: return SurfaceflingerStatsLayerInfo::GAME_MODE_BATTERY; default: return SurfaceflingerStatsLayerInfo::GAME_MODE_UNSPECIFIED; @@ -454,7 +454,7 @@ static int32_t clampToNearestBucket(Fps fps, size_t bucketWidth) { void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate, std::optional<Fps> renderRate, SetFrameRateVote frameRateVote, - int32_t gameMode) { + GameMode gameMode) { ATRACE_CALL(); ALOGV("[%d]-flushAvailableRecordsToStatsLocked", layerId); @@ -554,7 +554,7 @@ static bool layerNameIsValid(const std::string& layerName) { } bool TimeStats::canAddNewAggregatedStats(uid_t uid, const std::string& layerName, - int32_t gameMode) { + GameMode gameMode) { uint32_t layerRecords = 0; for (const auto& record : mTimeStats.stats) { if (record.second.stats.count({uid, layerName, gameMode}) > 0) { @@ -568,7 +568,7 @@ bool TimeStats::canAddNewAggregatedStats(uid_t uid, const std::string& layerName } void TimeStats::setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, - uid_t uid, nsecs_t postTime, int32_t gameMode) { + uid_t uid, nsecs_t postTime, GameMode gameMode) { if (!mEnabled.load()) return; ATRACE_CALL(); @@ -718,7 +718,7 @@ void TimeStats::setAcquireFence(int32_t layerId, uint64_t frameNumber, void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime, Fps displayRefreshRate, std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode) { + SetFrameRateVote frameRateVote, GameMode gameMode) { if (!mEnabled.load()) return; ATRACE_CALL(); @@ -744,7 +744,7 @@ void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t pr void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber, const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate, std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode) { + SetFrameRateVote frameRateVote, GameMode gameMode) { if (!mEnabled.load()) return; ATRACE_CALL(); @@ -823,7 +823,7 @@ void TimeStats::incrementJankyFrames(const JankyFramesInfo& info) { // the first jank record is not dropped. static const std::string kDefaultLayerName = "none"; - static constexpr int32_t kDefaultGameMode = TimeStatsHelper::GameModeUnsupported; + constexpr GameMode kDefaultGameMode = GameMode::Unsupported; const int32_t refreshRateBucket = clampToNearestBucket(info.refreshRate, REFRESH_RATE_BUCKET_WIDTH); diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h index 23f19b5cfd..77c7973532 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.h +++ b/services/surfaceflinger/TimeStats/TimeStats.h @@ -25,6 +25,7 @@ #include <android/hardware/graphics/composer/2.4/IComposerClient.h> #include <gui/JankInfo.h> +#include <gui/LayerMetadata.h> #include <timestatsproto/TimeStatsHelper.h> #include <timestatsproto/TimeStatsProtoHeader.h> #include <ui/FenceTime.h> @@ -79,7 +80,7 @@ public: const std::shared_ptr<FenceTime>& readyFence) = 0; virtual void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, - uid_t uid, nsecs_t postTime, int32_t gameMode) = 0; + uid_t uid, nsecs_t postTime, GameMode) = 0; virtual void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) = 0; // Reasons why latching a particular buffer may be skipped enum class LatchSkipReason { @@ -101,11 +102,11 @@ public: // rendering path, as they flush prior fences if those fences have fired. virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime, Fps displayRefreshRate, std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode) = 0; + SetFrameRateVote frameRateVote, GameMode) = 0; virtual void setPresentFence(int32_t layerId, uint64_t frameNumber, const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate, std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode) = 0; + SetFrameRateVote frameRateVote, GameMode) = 0; // Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName} // key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the @@ -123,7 +124,7 @@ public: std::optional<Fps> renderRate; uid_t uid = 0; std::string layerName; - int32_t gameMode = 0; + GameMode gameMode = GameMode::Unsupported; int32_t reasons = 0; nsecs_t displayDeadlineDelta = 0; nsecs_t displayPresentJitter = 0; @@ -194,7 +195,7 @@ class TimeStats : public android::TimeStats { struct LayerRecord { uid_t uid; std::string layerName; - int32_t gameMode = 0; + GameMode gameMode = GameMode::Unsupported; // This is the index in timeRecords, at which the timestamps for that // specific frame are still not fully received. This is not waiting for // fences to signal, but rather waiting to receive those fences/timestamps. @@ -247,7 +248,7 @@ public: const std::shared_ptr<FenceTime>& readyFence) override; void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, uid_t uid, - nsecs_t postTime, int32_t gameMode) override; + nsecs_t postTime, GameMode) override; void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) override; void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) override; void incrementBadDesiredPresent(int32_t layerId) override; @@ -256,12 +257,11 @@ public: void setAcquireFence(int32_t layerId, uint64_t frameNumber, const std::shared_ptr<FenceTime>& acquireFence) override; void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime, - Fps displayRefreshRate, std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode) override; + Fps displayRefreshRate, std::optional<Fps> renderRate, SetFrameRateVote, + GameMode) override; void setPresentFence(int32_t layerId, uint64_t frameNumber, const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate, - std::optional<Fps> renderRate, SetFrameRateVote frameRateVote, - int32_t gameMode) override; + std::optional<Fps> renderRate, SetFrameRateVote, GameMode) override; void incrementJankyFrames(const JankyFramesInfo& info) override; // Clean up the layer record @@ -282,11 +282,11 @@ private: bool populateLayerAtom(std::string* pulledData); bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord); void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate, - std::optional<Fps> renderRate, - SetFrameRateVote frameRateVote, int32_t gameMode); + std::optional<Fps> renderRate, SetFrameRateVote, + GameMode); void flushPowerTimeLocked(); void flushAvailableGlobalRecordsToStatsLocked(); - bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName, int32_t gameMode); + bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName, GameMode); void enable(); void disable(); diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp index ffb2f0921d..69afa2a7a1 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp +++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp @@ -16,9 +16,10 @@ #include "timestatsproto/TimeStatsHelper.h" #include <android-base/stringprintf.h> -#include <inttypes.h> +#include <ftl/enum.h> #include <array> +#include <cinttypes> #define HISTOGRAM_SIZE 85 @@ -91,51 +92,15 @@ std::string TimeStatsHelper::JankPayload::toString() const { return result; } -std::string TimeStatsHelper::SetFrameRateVote::toString(FrameRateCompatibility compatibility) { - switch (compatibility) { - case FrameRateCompatibility::Undefined: - return "Undefined"; - case FrameRateCompatibility::Default: - return "Default"; - case FrameRateCompatibility::ExactOrMultiple: - return "ExactOrMultiple"; - } -} - -std::string TimeStatsHelper::SetFrameRateVote::toString(Seamlessness seamlessness) { - switch (seamlessness) { - case Seamlessness::Undefined: - return "Undefined"; - case Seamlessness::ShouldBeSeamless: - return "ShouldBeSeamless"; - case Seamlessness::NotRequired: - return "NotRequired"; - } -} - std::string TimeStatsHelper::SetFrameRateVote::toString() const { std::string result; StringAppendF(&result, "frameRate = %.2f\n", frameRate); StringAppendF(&result, "frameRateCompatibility = %s\n", - toString(frameRateCompatibility).c_str()); - StringAppendF(&result, "seamlessness = %s\n", toString(seamlessness).c_str()); + ftl::enum_string(frameRateCompatibility).c_str()); + StringAppendF(&result, "seamlessness = %s\n", ftl::enum_string(seamlessness).c_str()); return result; } -std::string TimeStatsHelper::TimeStatsLayer::toString(int32_t gameMode) const { - switch (gameMode) { - case TimeStatsHelper::GameModeUnsupported: - return "GameModeUnsupported"; - case TimeStatsHelper::GameModeStandard: - return "GameModeStandard"; - case TimeStatsHelper::GameModePerformance: - return "GameModePerformance"; - case TimeStatsHelper::GameModeBattery: - return "GameModeBattery"; - default: - return "GameModeUnspecified"; - } -} std::string TimeStatsHelper::TimeStatsLayer::toString() const { std::string result = "\n"; StringAppendF(&result, "displayRefreshRate = %d fps\n", displayRefreshRateBucket); @@ -143,7 +108,7 @@ std::string TimeStatsHelper::TimeStatsLayer::toString() const { StringAppendF(&result, "uid = %d\n", uid); StringAppendF(&result, "layerName = %s\n", layerName.c_str()); StringAppendF(&result, "packageName = %s\n", packageName.c_str()); - StringAppendF(&result, "gameMode = %s\n", toString(gameMode).c_str()); + StringAppendF(&result, "gameMode = %s\n", ftl::enum_string(gameMode).c_str()); StringAppendF(&result, "totalFrames = %d\n", totalFrames); StringAppendF(&result, "droppedFrames = %d\n", droppedFrames); StringAppendF(&result, "lateAcquireFrames = %d\n", lateAcquireFrames); diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h index 2afff8d313..438561cc05 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h +++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h @@ -15,6 +15,7 @@ */ #pragma once +#include <gui/LayerMetadata.h> #include <timestatsproto/TimeStatsProtoHeader.h> #include <utils/Timers.h> @@ -63,6 +64,8 @@ public: Undefined = 0, Default = 1, ExactOrMultiple = 2, + + ftl_last = ExactOrMultiple } frameRateCompatibility = FrameRateCompatibility::Undefined; // Needs to be in sync with atoms.proto @@ -70,25 +73,13 @@ public: Undefined = 0, ShouldBeSeamless = 1, NotRequired = 2, + + ftl_last = NotRequired } seamlessness = Seamlessness::Undefined; - static std::string toString(FrameRateCompatibility); - static std::string toString(Seamlessness); std::string toString() const; }; - /** - * GameMode of the layer. GameModes are set by SysUI through WMShell. - * Actual game mode definitions are managed by GameManager.java - * The values defined here should always be in sync with the ones in GameManager. - */ - enum GameMode { - GameModeUnsupported = 0, - GameModeStandard = 1, - GameModePerformance = 2, - GameModeBattery = 3, - }; - class TimeStatsLayer { public: uid_t uid; @@ -96,7 +87,7 @@ public: std::string packageName; int32_t displayRefreshRateBucket = 0; int32_t renderRateBucket = 0; - int32_t gameMode = 0; + GameMode gameMode = GameMode::Unsupported; int32_t totalFrames = 0; int32_t droppedFrames = 0; int32_t lateAcquireFrames = 0; @@ -106,7 +97,6 @@ public: std::unordered_map<std::string, Histogram> deltas; std::string toString() const; - std::string toString(int32_t gameMode) const; SFTimeStatsLayerProto toProto() const; }; @@ -137,13 +127,14 @@ public: struct LayerStatsKey { uid_t uid = 0; std::string layerName; - int32_t gameMode = 0; + GameMode gameMode = GameMode::Unsupported; struct Hasher { size_t operator()(const LayerStatsKey& key) const { size_t uidHash = std::hash<uid_t>{}(key.uid); size_t layerNameHash = std::hash<std::string>{}(key.layerName); - size_t gameModeHash = std::hash<int32_t>{}(key.gameMode); + using T = std::underlying_type_t<GameMode>; + size_t gameModeHash = std::hash<T>{}(static_cast<T>(key.gameMode)); return HashCombine(uidHash, HashCombine(layerNameHash, gameModeHash)); } }; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 8d2c078305..c7c6b06386 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -370,7 +370,7 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _)).Times(1); EXPECT_CALL(*test->mDisplaySurface, - prepareFrame(compositionengine::DisplaySurface::COMPOSITION_HWC)) + prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc)) .Times(1); } @@ -384,7 +384,7 @@ struct BaseDisplayVariant { static void setupRECompositionCallExpectations(CompositionTest* test) { EXPECT_CALL(*test->mDisplaySurface, - prepareFrame(compositionengine::DisplaySurface::COMPOSITION_GPU)) + prepareFrame(compositionengine::DisplaySurface::CompositionType::Gpu)) .Times(1); EXPECT_CALL(*test->mDisplaySurface, getClientTargetAcquireFence()) .WillRepeatedly(ReturnRef(test->mClientTargetAcquireFence)); diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index 9fbaeced7b..397c6193bf 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -169,13 +169,14 @@ public: static const std::string sLayerNameOne = "layer1"; static const std::string sLayerNameTwo = "layer2"; -static constexpr const uid_t sUidOne = 0; -static constexpr pid_t sPidOne = 10; -static constexpr pid_t sPidTwo = 20; -static constexpr int32_t sInputEventId = 5; -static constexpr int32_t sLayerIdOne = 1; -static constexpr int32_t sLayerIdTwo = 2; -static constexpr int32_t sGameMode = 0; + +constexpr const uid_t sUidOne = 0; +constexpr pid_t sPidOne = 10; +constexpr pid_t sPidTwo = 20; +constexpr int32_t sInputEventId = 5; +constexpr int32_t sLayerIdOne = 1; +constexpr int32_t sLayerIdTwo = 2; +constexpr GameMode sGameMode = GameMode::Unsupported; TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) { int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0}); diff --git a/services/surfaceflinger/tests/unittests/GameModeTest.cpp b/services/surfaceflinger/tests/unittests/GameModeTest.cpp index d6459429fb..981ca1d227 100644 --- a/services/surfaceflinger/tests/unittests/GameModeTest.cpp +++ b/services/surfaceflinger/tests/unittests/GameModeTest.cpp @@ -91,8 +91,8 @@ public: } // Mocks the behavior of applying a transaction from WMShell - void setGameModeMetadata(sp<Layer> layer, int gameMode) { - mLayerMetadata.setInt32(METADATA_GAME_MODE, gameMode); + void setGameModeMetadata(sp<Layer> layer, GameMode gameMode) { + mLayerMetadata.setInt32(METADATA_GAME_MODE, static_cast<int32_t>(gameMode)); layer->setMetadata(mLayerMetadata); layer->setGameModeForTree(gameMode); } @@ -109,51 +109,52 @@ TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) { sp<BufferStateLayer> childLayer2 = createBufferStateLayer(); rootLayer->addChild(childLayer1); rootLayer->addChild(childLayer2); - rootLayer->setGameModeForTree(/*gameMode*/ 2); + rootLayer->setGameModeForTree(GameMode::Performance); - EXPECT_EQ(rootLayer->getGameMode(), 2); - EXPECT_EQ(childLayer1->getGameMode(), 2); - EXPECT_EQ(childLayer2->getGameMode(), 2); + EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance); + EXPECT_EQ(childLayer1->getGameMode(), GameMode::Performance); + EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance); } TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) { sp<BufferStateLayer> rootLayer = createBufferStateLayer(); sp<BufferStateLayer> childLayer = createBufferStateLayer(); - rootLayer->setGameModeForTree(/*gameMode*/ 2); + rootLayer->setGameModeForTree(GameMode::Performance); rootLayer->addChild(childLayer); - EXPECT_EQ(rootLayer->getGameMode(), 2); - EXPECT_EQ(childLayer->getGameMode(), 2); + EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance); + EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance); } TEST_F(GameModeTest, RemoveChildResetsGameMode) { sp<BufferStateLayer> rootLayer = createBufferStateLayer(); sp<BufferStateLayer> childLayer = createBufferStateLayer(); - rootLayer->setGameModeForTree(/*gameMode*/ 2); + rootLayer->setGameModeForTree(GameMode::Performance); rootLayer->addChild(childLayer); - EXPECT_EQ(rootLayer->getGameMode(), 2); - EXPECT_EQ(childLayer->getGameMode(), 2); + EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance); + EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance); rootLayer->removeChild(childLayer); - EXPECT_EQ(childLayer->getGameMode(), 0); + EXPECT_EQ(childLayer->getGameMode(), GameMode::Unsupported); } TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) { sp<BufferStateLayer> rootLayer = createBufferStateLayer(); sp<BufferStateLayer> childLayer1 = createBufferStateLayer(); sp<BufferStateLayer> childLayer2 = createBufferStateLayer(); - rootLayer->setGameModeForTree(/*gameMode*/ 1); + rootLayer->setGameModeForTree(GameMode::Standard); rootLayer->addChild(childLayer1); - setGameModeMetadata(childLayer2, /*gameMode*/ 2); + setGameModeMetadata(childLayer2, GameMode::Performance); rootLayer->addChild(childLayer2); - EXPECT_EQ(rootLayer->getGameMode(), 1); - EXPECT_EQ(childLayer1->getGameMode(), 1); - EXPECT_EQ(childLayer2->getGameMode(), 2); + EXPECT_EQ(rootLayer->getGameMode(), GameMode::Standard); + EXPECT_EQ(childLayer1->getGameMode(), GameMode::Standard); + EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance); rootLayer->removeChild(childLayer2); - EXPECT_EQ(childLayer2->getGameMode(), 2); + EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance); } -} // namespace android
\ No newline at end of file + +} // namespace android diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp index fc84d48b46..98746bcd21 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp @@ -21,10 +21,9 @@ #undef LOG_TAG #define LOG_TAG "SchedulerUnittests" +#include <ftl/enum.h> #include <gmock/gmock.h> #include <log/log.h> -#include <thread> - #include <ui/Size.h> #include "DisplayHardware/HWC2.h" @@ -1975,7 +1974,7 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_deviceWithCloseRefreshRates) { layers[0].vote = vote; EXPECT_EQ(fps.getIntValue(), refreshRateConfigs->getBestRefreshRate(layers, {}).getFps().getIntValue()) - << "Failed for " << RefreshRateConfigs::layerVoteTypeString(vote); + << "Failed for " << ftl::enum_string(vote); }; for (int fps = kMinRefreshRate; fps < kMaxRefreshRate; fps++) { diff --git a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp index 1487a962f9..0ef8456739 100644 --- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp +++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp @@ -70,9 +70,9 @@ using SurfaceflingerStatsLayerInfoWrapper = #define NUM_LAYERS 1 #define NUM_LAYERS_INVALID "INVALID" -const constexpr Fps kRefreshRate0 = 61_Hz; -const constexpr Fps kRenderRate0 = 31_Hz; -static constexpr int32_t kGameMode = TimeStatsHelper::GameModeUnsupported; +constexpr Fps kRefreshRate0 = 61_Hz; +constexpr Fps kRenderRate0 = 31_Hz; +constexpr GameMode kGameMode = GameMode::Unsupported; enum InputCommand : int32_t { ENABLE = 0, @@ -145,14 +145,14 @@ public: std::string inputCommand(InputCommand cmd, bool useProto); void setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts, - TimeStats::SetFrameRateVote frameRateVote, int32_t gameMode); + TimeStats::SetFrameRateVote, GameMode); int32_t genRandomInt32(int32_t begin, int32_t end); template <size_t N> void insertTimeRecord(const TimeStamp (&sequence)[N], int32_t id, uint64_t frameNumber, nsecs_t ts, TimeStats::SetFrameRateVote frameRateVote = {}, - int32_t gameMode = kGameMode) { + GameMode gameMode = kGameMode) { for (size_t i = 0; i < N; i++, ts += 1000000) { setTimeStamp(sequence[i], id, frameNumber, ts, frameRateVote, gameMode); } @@ -203,7 +203,7 @@ static std::string genLayerName(int32_t layerId) { } void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts, - TimeStats::SetFrameRateVote frameRateVote, int32_t gameMode) { + TimeStats::SetFrameRateVote frameRateVote, GameMode gameMode) { switch (type) { case TimeStamp::POST: ASSERT_NO_FATAL_FAILURE(mTimeStats->setPostTime(id, frameNumber, genLayerName(id), @@ -1168,8 +1168,7 @@ TEST_F(TimeStatsTest, layerStatsCallback_pullsAllAndClears) { constexpr nsecs_t APP_DEADLINE_DELTA_3MS = 3'000'000; EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty()); - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {}, - TimeStatsHelper::GameModeStandard); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {}, GameMode::Standard); for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) { mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire); } @@ -1182,42 +1181,39 @@ TEST_F(TimeStatsTest, layerStatsCallback_pullsAllAndClears) { TimeStats::SetFrameRateVote::FrameRateCompatibility::ExactOrMultiple, .seamlessness = TimeStats::SetFrameRateVote::Seamlessness::NotRequired, }; - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, frameRate60, - TimeStatsHelper::GameModeStandard); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, frameRate60, GameMode::Standard); - mTimeStats->incrementJankyFrames( - {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, JankType::SurfaceFlingerCpuDeadlineMissed, - DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS}); - mTimeStats->incrementJankyFrames( - {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, JankType::SurfaceFlingerGpuDeadlineMissed, - DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, JankType::DisplayHAL, + GameMode::Standard, JankType::SurfaceFlingerCpuDeadlineMissed, DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, - JankType::AppDeadlineMissed, DISPLAY_DEADLINE_DELTA, - DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS}); + GameMode::Standard, JankType::SurfaceFlingerGpuDeadlineMissed, + DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, + APP_DEADLINE_DELTA_3MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, - JankType::SurfaceFlingerScheduling, DISPLAY_DEADLINE_DELTA, - DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_2MS}); + GameMode::Standard, JankType::DisplayHAL, + DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, + APP_DEADLINE_DELTA_3MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, JankType::PredictionError, + GameMode::Standard, JankType::AppDeadlineMissed, DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, - APP_DEADLINE_DELTA_2MS}); + APP_DEADLINE_DELTA_3MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, - JankType::AppDeadlineMissed | JankType::BufferStuffing, - DISPLAY_DEADLINE_DELTA, APP_DEADLINE_DELTA_2MS, + GameMode::Standard, JankType::SurfaceFlingerScheduling, + DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_2MS}); mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), - TimeStatsHelper::GameModeStandard, JankType::None, + GameMode::Standard, JankType::PredictionError, DISPLAY_DEADLINE_DELTA, DISPLAY_PRESENT_JITTER, - APP_DEADLINE_DELTA_3MS}); + APP_DEADLINE_DELTA_2MS}); + mTimeStats->incrementJankyFrames( + {kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), GameMode::Standard, + JankType::AppDeadlineMissed | JankType::BufferStuffing, DISPLAY_DEADLINE_DELTA, + APP_DEADLINE_DELTA_2MS, APP_DEADLINE_DELTA_2MS}); + mTimeStats->incrementJankyFrames({kRefreshRate0, kRenderRate0, UID_0, genLayerName(LAYER_ID_0), + GameMode::Standard, JankType::None, DISPLAY_DEADLINE_DELTA, + DISPLAY_PRESENT_JITTER, APP_DEADLINE_DELTA_3MS}); std::string pulledData; EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData)); @@ -1293,22 +1289,18 @@ TEST_F(TimeStatsTest, layerStatsCallback_multipleGameModes) { constexpr size_t BAD_DESIRED_PRESENT_FRAMES = 3; EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty()); - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {}, - TimeStatsHelper::GameModeStandard); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 1, 1000000, {}, GameMode::Standard); for (size_t i = 0; i < LATE_ACQUIRE_FRAMES; i++) { mTimeStats->incrementLatchSkipped(LAYER_ID_0, TimeStats::LatchSkipReason::LateAcquire); } for (size_t i = 0; i < BAD_DESIRED_PRESENT_FRAMES; i++) { mTimeStats->incrementBadDesiredPresent(LAYER_ID_0); } - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, {}, - TimeStatsHelper::GameModeStandard); - - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000, {}, - TimeStatsHelper::GameModePerformance); - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 4000000, {}, TimeStatsHelper::GameModeBattery); - insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 5, 4000000, {}, TimeStatsHelper::GameModeBattery); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 2, 2000000, {}, GameMode::Standard); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 3, 3000000, {}, GameMode::Performance); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 4000000, {}, GameMode::Battery); + insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 5, 4000000, {}, GameMode::Battery); std::string pulledData; EXPECT_TRUE(mTimeStats->onPullAtom(10063 /*SURFACEFLINGER_STATS_LAYER_INFO*/, &pulledData)); diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h index 5aebd2f20e..0a69b562ab 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h +++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h @@ -41,19 +41,21 @@ public: MOCK_METHOD2(recordFrameDuration, void(nsecs_t, nsecs_t)); MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, nsecs_t)); MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, const std::shared_ptr<FenceTime>&)); - MOCK_METHOD6(setPostTime, void(int32_t, uint64_t, const std::string&, uid_t, nsecs_t, int32_t)); + MOCK_METHOD(void, setPostTime, + (int32_t, uint64_t, const std::string&, uid_t, nsecs_t, GameMode), (override)); MOCK_METHOD2(incrementLatchSkipped, void(int32_t layerId, LatchSkipReason reason)); MOCK_METHOD1(incrementBadDesiredPresent, void(int32_t layerId)); MOCK_METHOD3(setLatchTime, void(int32_t, uint64_t, nsecs_t)); MOCK_METHOD3(setDesiredTime, void(int32_t, uint64_t, nsecs_t)); MOCK_METHOD3(setAcquireTime, void(int32_t, uint64_t, nsecs_t)); MOCK_METHOD3(setAcquireFence, void(int32_t, uint64_t, const std::shared_ptr<FenceTime>&)); - MOCK_METHOD7(setPresentTime, - void(int32_t, uint64_t, nsecs_t, Fps, std::optional<Fps>, SetFrameRateVote, - int32_t)); - MOCK_METHOD7(setPresentFence, - void(int32_t, uint64_t, const std::shared_ptr<FenceTime>&, Fps, std::optional<Fps>, - SetFrameRateVote, int32_t)); + MOCK_METHOD(void, setPresentTime, + (int32_t, uint64_t, nsecs_t, Fps, std::optional<Fps>, SetFrameRateVote, GameMode), + (override)); + MOCK_METHOD(void, setPresentFence, + (int32_t, uint64_t, const std::shared_ptr<FenceTime>&, Fps, std::optional<Fps>, + SetFrameRateVote, GameMode), + (override)); MOCK_METHOD1(incrementJankyFrames, void(const JankyFramesInfo&)); MOCK_METHOD1(onDestroy, void(int32_t)); MOCK_METHOD2(removeTimeRecord, void(int32_t, uint64_t)); |