Loading services/surfaceflinger/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ cc_defaults { // TODO (marissaw): this library is not used by surfaceflinger. This is here so // the library compiled in a way that is accessible to system partition when running // IMapper's VTS. required: ["libgralloctypes"] required: ["libgralloctypes"], } cc_defaults { Loading Loading @@ -191,6 +191,7 @@ filegroup { "SurfaceFlingerDefaultFactory.cpp", "SurfaceInterceptor.cpp", "SurfaceTracing.cpp", "Tracing/TransactionProtoParser.cpp", "TransactionCallbackInvoker.cpp", "TunnelModeEnabledReporter.cpp", ], Loading services/surfaceflinger/LayerProtoHelper.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -53,26 +53,50 @@ void LayerProtoHelper::writeToProto(const Region& region, return; } writeToProto(region, getRegionProto()); } void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionProto) { if (region.isEmpty()) { return; } Region::const_iterator head = region.begin(); Region::const_iterator const tail = region.end(); // Use a lambda do avoid writing the object header when the object is empty RegionProto* regionProto = getRegionProto(); while (head != tail) { std::function<RectProto*()> getProtoRect = [&]() { return regionProto->add_rect(); }; writeToProto(*head, getProtoRect); writeToProto(*head, regionProto->add_rect()); head++; } } void LayerProtoHelper::readFromProto(const RegionProto& regionProto, Region& outRegion) { for (int i = 0; i < regionProto.rect_size(); i++) { Rect rect; readFromProto(regionProto.rect(i), rect); outRegion.orSelf(rect); } } void LayerProtoHelper::writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto) { if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) { // Use a lambda do avoid writing the object header when the object is empty RectProto* rectProto = getRectProto(); writeToProto(rect, getRectProto()); } } void LayerProtoHelper::writeToProto(const Rect& rect, RectProto* rectProto) { rectProto->set_left(rect.left); rectProto->set_top(rect.top); rectProto->set_bottom(rect.bottom); rectProto->set_right(rect.right); } void LayerProtoHelper::readFromProto(const RectProto& proto, Rect& outRect) { outRect.left = proto.left(); outRect.top = proto.top(); outRect.bottom = proto.bottom(); outRect.right = proto.right(); } void LayerProtoHelper::writeToProto(const FloatRect& rect, Loading Loading @@ -189,6 +213,39 @@ void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colo } } void LayerProtoHelper::readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix) { for (int i = 0; i < mat4::ROW_SIZE; i++) { for (int j = 0; j < mat4::COL_SIZE; j++) { matrix[i][j] = colorTransformProto.val(i * mat4::COL_SIZE + j); } } } void LayerProtoHelper::writeToProto(const android::BlurRegion region, BlurRegion* proto) { proto->set_blur_radius(region.blurRadius); proto->set_corner_radius_tl(region.cornerRadiusTL); proto->set_corner_radius_tr(region.cornerRadiusTR); proto->set_corner_radius_bl(region.cornerRadiusBL); proto->set_corner_radius_br(region.cornerRadiusBR); proto->set_alpha(region.alpha); proto->set_left(region.left); proto->set_top(region.top); proto->set_right(region.right); proto->set_bottom(region.bottom); } void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion) { outRegion.blurRadius = proto.blur_radius(); outRegion.cornerRadiusTL = proto.corner_radius_tl(); outRegion.cornerRadiusTR = proto.corner_radius_tr(); outRegion.cornerRadiusBL = proto.corner_radius_bl(); outRegion.cornerRadiusBR = proto.corner_radius_br(); outRegion.alpha = proto.alpha(); outRegion.left = proto.left(); outRegion.top = proto.top(); outRegion.right = proto.right(); outRegion.bottom = proto.bottom(); } } // namespace surfaceflinger } // namespace android Loading services/surfaceflinger/LayerProtoHelper.h +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <Layer.h> #include <gui/WindowInfo.h> #include <math/vec4.h> #include <ui/BlurRegion.h> #include <ui/GraphicBuffer.h> #include <ui/Rect.h> #include <ui/Region.h> Loading @@ -33,9 +34,13 @@ public: static void writeSizeToProto(const uint32_t w, const uint32_t h, std::function<SizeProto*()> getSizeProto); static void writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto); static void writeToProto(const Rect& rect, RectProto* rectProto); static void readFromProto(const RectProto& proto, Rect& outRect); static void writeToProto(const FloatRect& rect, std::function<FloatRectProto*()> getFloatRectProto); static void writeToProto(const Region& region, std::function<RegionProto*()> getRegionProto); static void writeToProto(const Region& region, RegionProto* regionProto); static void readFromProto(const RegionProto& regionProto, Region& outRegion); static void writeToProto(const half4 color, std::function<ColorProto*()> getColorProto); // This writeToProto for transform is incorrect, but due to backwards compatibility, we can't // update Layers to use it. Use writeTransformToProto for any new transform proto data. Loading @@ -49,6 +54,9 @@ public: const wp<Layer>& touchableRegionBounds, std::function<InputWindowInfoProto*()> getInputWindowInfoProto); static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto); static void readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix); static void writeToProto(const android::BlurRegion region, BlurRegion*); static void readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion); }; } // namespace surfaceflinger Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -6787,7 +6787,7 @@ int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) con return calculateMaxAcquiredBufferCount(refreshRate, presentLatency); } void SurfaceFlinger::TransactionState::traverseStatesWithBuffers( void TransactionState::traverseStatesWithBuffers( std::function<void(const layer_state_t&)> visitor) { for (const auto& state : states) { if (state.state.hasBufferChanges() && state.state.hasValidBuffer() && state.state.surface) { Loading services/surfaceflinger/SurfaceFlinger.h +1 −90 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ #include "SurfaceTracing.h" #include "TracedOrdinal.h" #include "TransactionCallbackInvoker.h" #include "TransactionState.h" #include <atomic> #include <cstdint> Loading Loading @@ -461,96 +462,6 @@ private: hal::Connection connection = hal::Connection::INVALID; }; class CountDownLatch { public: enum { eSyncTransaction = 1 << 0, eSyncInputWindows = 1 << 1, }; explicit CountDownLatch(uint32_t flags) : mFlags(flags) {} // True if there is no waiting condition after count down. bool countDown(uint32_t flag) { std::unique_lock<std::mutex> lock(mMutex); if (mFlags == 0) { return true; } mFlags &= ~flag; if (mFlags == 0) { mCountDownComplete.notify_all(); return true; } return false; } // Return true if triggered. bool wait_until(const std::chrono::seconds& timeout) const { std::unique_lock<std::mutex> lock(mMutex); const auto untilTime = std::chrono::system_clock::now() + timeout; while (mFlags != 0) { // Conditional variables can be woken up sporadically, so we check count // to verify the wakeup was triggered by |countDown|. if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) { return false; } } return true; } private: uint32_t mFlags; mutable std::condition_variable mCountDownComplete; mutable std::mutex mMutex; }; struct TransactionState { TransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& composerStates, const Vector<DisplayState>& displayStates, uint32_t transactionFlags, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks, int originPid, int originUid, uint64_t transactionId) : frameTimelineInfo(frameTimelineInfo), states(composerStates), displays(displayStates), flags(transactionFlags), applyToken(applyToken), inputWindowCommands(inputWindowCommands), desiredPresentTime(desiredPresentTime), isAutoTimestamp(isAutoTimestamp), buffer(uncacheBuffer), postTime(postTime), permissions(permissions), hasListenerCallbacks(hasListenerCallbacks), listenerCallbacks(listenerCallbacks), originPid(originPid), originUid(originUid), id(transactionId) {} void traverseStatesWithBuffers(std::function<void(const layer_state_t&)> visitor); FrameTimelineInfo frameTimelineInfo; Vector<ComposerState> states; Vector<DisplayState> displays; uint32_t flags; sp<IBinder> applyToken; InputWindowCommands inputWindowCommands; const int64_t desiredPresentTime; const bool isAutoTimestamp; client_cache_t buffer; const int64_t postTime; uint32_t permissions; bool hasListenerCallbacks; std::vector<ListenerCallbacks> listenerCallbacks; int originPid; int originUid; uint64_t id; std::shared_ptr<CountDownLatch> transactionCommittedSignal; }; template <typename F, std::enable_if_t<!std::is_member_function_pointer_v<F>>* = nullptr> static Dumper dumper(F&& dump) { using namespace std::placeholders; Loading Loading
services/surfaceflinger/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ cc_defaults { // TODO (marissaw): this library is not used by surfaceflinger. This is here so // the library compiled in a way that is accessible to system partition when running // IMapper's VTS. required: ["libgralloctypes"] required: ["libgralloctypes"], } cc_defaults { Loading Loading @@ -191,6 +191,7 @@ filegroup { "SurfaceFlingerDefaultFactory.cpp", "SurfaceInterceptor.cpp", "SurfaceTracing.cpp", "Tracing/TransactionProtoParser.cpp", "TransactionCallbackInvoker.cpp", "TunnelModeEnabledReporter.cpp", ], Loading
services/surfaceflinger/LayerProtoHelper.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -53,26 +53,50 @@ void LayerProtoHelper::writeToProto(const Region& region, return; } writeToProto(region, getRegionProto()); } void LayerProtoHelper::writeToProto(const Region& region, RegionProto* regionProto) { if (region.isEmpty()) { return; } Region::const_iterator head = region.begin(); Region::const_iterator const tail = region.end(); // Use a lambda do avoid writing the object header when the object is empty RegionProto* regionProto = getRegionProto(); while (head != tail) { std::function<RectProto*()> getProtoRect = [&]() { return regionProto->add_rect(); }; writeToProto(*head, getProtoRect); writeToProto(*head, regionProto->add_rect()); head++; } } void LayerProtoHelper::readFromProto(const RegionProto& regionProto, Region& outRegion) { for (int i = 0; i < regionProto.rect_size(); i++) { Rect rect; readFromProto(regionProto.rect(i), rect); outRegion.orSelf(rect); } } void LayerProtoHelper::writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto) { if (rect.left != 0 || rect.right != 0 || rect.top != 0 || rect.bottom != 0) { // Use a lambda do avoid writing the object header when the object is empty RectProto* rectProto = getRectProto(); writeToProto(rect, getRectProto()); } } void LayerProtoHelper::writeToProto(const Rect& rect, RectProto* rectProto) { rectProto->set_left(rect.left); rectProto->set_top(rect.top); rectProto->set_bottom(rect.bottom); rectProto->set_right(rect.right); } void LayerProtoHelper::readFromProto(const RectProto& proto, Rect& outRect) { outRect.left = proto.left(); outRect.top = proto.top(); outRect.bottom = proto.bottom(); outRect.right = proto.right(); } void LayerProtoHelper::writeToProto(const FloatRect& rect, Loading Loading @@ -189,6 +213,39 @@ void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colo } } void LayerProtoHelper::readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix) { for (int i = 0; i < mat4::ROW_SIZE; i++) { for (int j = 0; j < mat4::COL_SIZE; j++) { matrix[i][j] = colorTransformProto.val(i * mat4::COL_SIZE + j); } } } void LayerProtoHelper::writeToProto(const android::BlurRegion region, BlurRegion* proto) { proto->set_blur_radius(region.blurRadius); proto->set_corner_radius_tl(region.cornerRadiusTL); proto->set_corner_radius_tr(region.cornerRadiusTR); proto->set_corner_radius_bl(region.cornerRadiusBL); proto->set_corner_radius_br(region.cornerRadiusBR); proto->set_alpha(region.alpha); proto->set_left(region.left); proto->set_top(region.top); proto->set_right(region.right); proto->set_bottom(region.bottom); } void LayerProtoHelper::readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion) { outRegion.blurRadius = proto.blur_radius(); outRegion.cornerRadiusTL = proto.corner_radius_tl(); outRegion.cornerRadiusTR = proto.corner_radius_tr(); outRegion.cornerRadiusBL = proto.corner_radius_bl(); outRegion.cornerRadiusBR = proto.corner_radius_br(); outRegion.alpha = proto.alpha(); outRegion.left = proto.left(); outRegion.top = proto.top(); outRegion.right = proto.right(); outRegion.bottom = proto.bottom(); } } // namespace surfaceflinger } // namespace android Loading
services/surfaceflinger/LayerProtoHelper.h +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <Layer.h> #include <gui/WindowInfo.h> #include <math/vec4.h> #include <ui/BlurRegion.h> #include <ui/GraphicBuffer.h> #include <ui/Rect.h> #include <ui/Region.h> Loading @@ -33,9 +34,13 @@ public: static void writeSizeToProto(const uint32_t w, const uint32_t h, std::function<SizeProto*()> getSizeProto); static void writeToProto(const Rect& rect, std::function<RectProto*()> getRectProto); static void writeToProto(const Rect& rect, RectProto* rectProto); static void readFromProto(const RectProto& proto, Rect& outRect); static void writeToProto(const FloatRect& rect, std::function<FloatRectProto*()> getFloatRectProto); static void writeToProto(const Region& region, std::function<RegionProto*()> getRegionProto); static void writeToProto(const Region& region, RegionProto* regionProto); static void readFromProto(const RegionProto& regionProto, Region& outRegion); static void writeToProto(const half4 color, std::function<ColorProto*()> getColorProto); // This writeToProto for transform is incorrect, but due to backwards compatibility, we can't // update Layers to use it. Use writeTransformToProto for any new transform proto data. Loading @@ -49,6 +54,9 @@ public: const wp<Layer>& touchableRegionBounds, std::function<InputWindowInfoProto*()> getInputWindowInfoProto); static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto); static void readFromProto(const ColorTransformProto& colorTransformProto, mat4& matrix); static void writeToProto(const android::BlurRegion region, BlurRegion*); static void readFromProto(const BlurRegion& proto, android::BlurRegion& outRegion); }; } // namespace surfaceflinger Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -6787,7 +6787,7 @@ int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) con return calculateMaxAcquiredBufferCount(refreshRate, presentLatency); } void SurfaceFlinger::TransactionState::traverseStatesWithBuffers( void TransactionState::traverseStatesWithBuffers( std::function<void(const layer_state_t&)> visitor) { for (const auto& state : states) { if (state.state.hasBufferChanges() && state.state.hasValidBuffer() && state.state.surface) { Loading
services/surfaceflinger/SurfaceFlinger.h +1 −90 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ #include "SurfaceTracing.h" #include "TracedOrdinal.h" #include "TransactionCallbackInvoker.h" #include "TransactionState.h" #include <atomic> #include <cstdint> Loading Loading @@ -461,96 +462,6 @@ private: hal::Connection connection = hal::Connection::INVALID; }; class CountDownLatch { public: enum { eSyncTransaction = 1 << 0, eSyncInputWindows = 1 << 1, }; explicit CountDownLatch(uint32_t flags) : mFlags(flags) {} // True if there is no waiting condition after count down. bool countDown(uint32_t flag) { std::unique_lock<std::mutex> lock(mMutex); if (mFlags == 0) { return true; } mFlags &= ~flag; if (mFlags == 0) { mCountDownComplete.notify_all(); return true; } return false; } // Return true if triggered. bool wait_until(const std::chrono::seconds& timeout) const { std::unique_lock<std::mutex> lock(mMutex); const auto untilTime = std::chrono::system_clock::now() + timeout; while (mFlags != 0) { // Conditional variables can be woken up sporadically, so we check count // to verify the wakeup was triggered by |countDown|. if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) { return false; } } return true; } private: uint32_t mFlags; mutable std::condition_variable mCountDownComplete; mutable std::mutex mMutex; }; struct TransactionState { TransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& composerStates, const Vector<DisplayState>& displayStates, uint32_t transactionFlags, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks, int originPid, int originUid, uint64_t transactionId) : frameTimelineInfo(frameTimelineInfo), states(composerStates), displays(displayStates), flags(transactionFlags), applyToken(applyToken), inputWindowCommands(inputWindowCommands), desiredPresentTime(desiredPresentTime), isAutoTimestamp(isAutoTimestamp), buffer(uncacheBuffer), postTime(postTime), permissions(permissions), hasListenerCallbacks(hasListenerCallbacks), listenerCallbacks(listenerCallbacks), originPid(originPid), originUid(originUid), id(transactionId) {} void traverseStatesWithBuffers(std::function<void(const layer_state_t&)> visitor); FrameTimelineInfo frameTimelineInfo; Vector<ComposerState> states; Vector<DisplayState> displays; uint32_t flags; sp<IBinder> applyToken; InputWindowCommands inputWindowCommands; const int64_t desiredPresentTime; const bool isAutoTimestamp; client_cache_t buffer; const int64_t postTime; uint32_t permissions; bool hasListenerCallbacks; std::vector<ListenerCallbacks> listenerCallbacks; int originPid; int originUid; uint64_t id; std::shared_ptr<CountDownLatch> transactionCommittedSignal; }; template <typename F, std::enable_if_t<!std::is_member_function_pointer_v<F>>* = nullptr> static Dumper dumper(F&& dump) { using namespace std::placeholders; Loading