Loading libs/hwui/FrameInfo.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ #include "FrameInfo.h" #include <gui/TraceUtils.h> #include <cstring> namespace android { Loading Loading @@ -51,6 +53,30 @@ static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 23, void FrameInfo::importUiThreadInfo(int64_t* info) { memcpy(mFrameInfo, info, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t)); mSkippedFrameReason.reset(); } const char* toString(SkippedFrameReason reason) { switch (reason) { case SkippedFrameReason::DrawingOff: return "DrawingOff"; case SkippedFrameReason::ContextIsStopped: return "ContextIsStopped"; case SkippedFrameReason::NothingToDraw: return "NothingToDraw"; case SkippedFrameReason::NoOutputTarget: return "NoOutputTarget"; case SkippedFrameReason::NoBuffer: return "NoBuffer"; case SkippedFrameReason::AlreadyDrawn: return "AlreadyDrawn"; } } void FrameInfo::setSkippedFrameReason(android::uirenderer::SkippedFrameReason reason) { ATRACE_FORMAT_INSTANT("Frame skipped: %s", toString(reason)); addFlag(FrameInfoFlags::SkippedFrame); mSkippedFrameReason = reason; } } /* namespace uirenderer */ Loading libs/hwui/FrameInfo.h +11 −3 Original line number Diff line number Diff line Loading @@ -16,15 +16,17 @@ #ifndef FRAMEINFO_H_ #define FRAMEINFO_H_ #include "utils/Macros.h" #include <cutils/compiler.h> #include <memory.h> #include <utils/Timers.h> #include <array> #include <memory.h> #include <optional> #include <string> #include "SkippedFrameInfo.h" #include "utils/Macros.h" namespace android { namespace uirenderer { Loading Loading @@ -186,8 +188,14 @@ public: return mFrameInfo[static_cast<int>(index)]; } void setSkippedFrameReason(SkippedFrameReason reason); inline std::optional<SkippedFrameReason> getSkippedFrameReason() const { return mSkippedFrameReason; } private: int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)]; std::optional<SkippedFrameReason> mSkippedFrameReason; }; } /* namespace uirenderer */ Loading libs/hwui/FrameInfoVisualizer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -148,7 +148,7 @@ void FrameInfoVisualizer::initializeRects(const int baseline, const int width) { int fast_i = 0, janky_i = 0; // Set the bottom of all the shapes to the baseline for (int fi = mFrameSource.size() - 1; fi >= 0; fi--) { if (mFrameSource[fi][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) { if (mFrameSource[fi].getSkippedFrameReason()) { continue; } float lineWidth = baseLineWidth; Loading Loading @@ -181,7 +181,7 @@ void FrameInfoVisualizer::nextBarSegment(FrameInfoIndex start, FrameInfoIndex en int janky_i = (mNumJankyRects - 1) * 4; for (size_t fi = 0; fi < mFrameSource.size(); fi++) { if (mFrameSource[fi][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) { if (mFrameSource[fi].getSkippedFrameReason()) { continue; } Loading libs/hwui/SkippedFrameInfo.h 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once namespace android::uirenderer { enum class SkippedFrameReason { DrawingOff, ContextIsStopped, NothingToDraw, NoOutputTarget, NoBuffer, AlreadyDrawn, }; } /* namespace android::uirenderer */ libs/hwui/TreeInfo.h +10 −8 Original line number Diff line number Diff line Loading @@ -16,14 +16,16 @@ #pragma once #include "Properties.h" #include "utils/Macros.h" #include <utils/Timers.h> #include "SkSize.h" #include <optional> #include <string> #include "Properties.h" #include "SkSize.h" #include "SkippedFrameInfo.h" #include "utils/Macros.h" namespace android { namespace uirenderer { Loading Loading @@ -110,13 +112,13 @@ public: // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true bool requiresUiRedraw = false; // This is set to true if draw() can be called this frame // false means that we must delay until the next vsync pulse as frame // This is set to nullopt if draw() can be called this frame // A value means that we must delay until the next vsync pulse as frame // production is outrunning consumption // NOTE that if this is false CanvasContext will set either requiresUiRedraw // NOTE that if this has a value CanvasContext will set either requiresUiRedraw // *OR* will post itself for the next vsync automatically, use this // only to avoid calling draw() bool canDrawThisFrame = true; std::optional<SkippedFrameReason> skippedFrameReason; // Sentinel for animatedImageDelay meaning there is no need to post such // a message. static constexpr nsecs_t kNoAnimatedImageDelay = -1; Loading Loading
libs/hwui/FrameInfo.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ #include "FrameInfo.h" #include <gui/TraceUtils.h> #include <cstring> namespace android { Loading Loading @@ -51,6 +53,30 @@ static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 23, void FrameInfo::importUiThreadInfo(int64_t* info) { memcpy(mFrameInfo, info, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t)); mSkippedFrameReason.reset(); } const char* toString(SkippedFrameReason reason) { switch (reason) { case SkippedFrameReason::DrawingOff: return "DrawingOff"; case SkippedFrameReason::ContextIsStopped: return "ContextIsStopped"; case SkippedFrameReason::NothingToDraw: return "NothingToDraw"; case SkippedFrameReason::NoOutputTarget: return "NoOutputTarget"; case SkippedFrameReason::NoBuffer: return "NoBuffer"; case SkippedFrameReason::AlreadyDrawn: return "AlreadyDrawn"; } } void FrameInfo::setSkippedFrameReason(android::uirenderer::SkippedFrameReason reason) { ATRACE_FORMAT_INSTANT("Frame skipped: %s", toString(reason)); addFlag(FrameInfoFlags::SkippedFrame); mSkippedFrameReason = reason; } } /* namespace uirenderer */ Loading
libs/hwui/FrameInfo.h +11 −3 Original line number Diff line number Diff line Loading @@ -16,15 +16,17 @@ #ifndef FRAMEINFO_H_ #define FRAMEINFO_H_ #include "utils/Macros.h" #include <cutils/compiler.h> #include <memory.h> #include <utils/Timers.h> #include <array> #include <memory.h> #include <optional> #include <string> #include "SkippedFrameInfo.h" #include "utils/Macros.h" namespace android { namespace uirenderer { Loading Loading @@ -186,8 +188,14 @@ public: return mFrameInfo[static_cast<int>(index)]; } void setSkippedFrameReason(SkippedFrameReason reason); inline std::optional<SkippedFrameReason> getSkippedFrameReason() const { return mSkippedFrameReason; } private: int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)]; std::optional<SkippedFrameReason> mSkippedFrameReason; }; } /* namespace uirenderer */ Loading
libs/hwui/FrameInfoVisualizer.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -148,7 +148,7 @@ void FrameInfoVisualizer::initializeRects(const int baseline, const int width) { int fast_i = 0, janky_i = 0; // Set the bottom of all the shapes to the baseline for (int fi = mFrameSource.size() - 1; fi >= 0; fi--) { if (mFrameSource[fi][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) { if (mFrameSource[fi].getSkippedFrameReason()) { continue; } float lineWidth = baseLineWidth; Loading Loading @@ -181,7 +181,7 @@ void FrameInfoVisualizer::nextBarSegment(FrameInfoIndex start, FrameInfoIndex en int janky_i = (mNumJankyRects - 1) * 4; for (size_t fi = 0; fi < mFrameSource.size(); fi++) { if (mFrameSource[fi][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) { if (mFrameSource[fi].getSkippedFrameReason()) { continue; } Loading
libs/hwui/SkippedFrameInfo.h 0 → 100644 +30 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once namespace android::uirenderer { enum class SkippedFrameReason { DrawingOff, ContextIsStopped, NothingToDraw, NoOutputTarget, NoBuffer, AlreadyDrawn, }; } /* namespace android::uirenderer */
libs/hwui/TreeInfo.h +10 −8 Original line number Diff line number Diff line Loading @@ -16,14 +16,16 @@ #pragma once #include "Properties.h" #include "utils/Macros.h" #include <utils/Timers.h> #include "SkSize.h" #include <optional> #include <string> #include "Properties.h" #include "SkSize.h" #include "SkippedFrameInfo.h" #include "utils/Macros.h" namespace android { namespace uirenderer { Loading Loading @@ -110,13 +112,13 @@ public: // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true bool requiresUiRedraw = false; // This is set to true if draw() can be called this frame // false means that we must delay until the next vsync pulse as frame // This is set to nullopt if draw() can be called this frame // A value means that we must delay until the next vsync pulse as frame // production is outrunning consumption // NOTE that if this is false CanvasContext will set either requiresUiRedraw // NOTE that if this has a value CanvasContext will set either requiresUiRedraw // *OR* will post itself for the next vsync automatically, use this // only to avoid calling draw() bool canDrawThisFrame = true; std::optional<SkippedFrameReason> skippedFrameReason; // Sentinel for animatedImageDelay meaning there is no need to post such // a message. static constexpr nsecs_t kNoAnimatedImageDelay = -1; Loading