Merge "Dither HDR content when compositing to an 8-bit target" into tm-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 24b201f..890c15f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2733,8 +2733,8 @@
                                         const android::base::unique_fd& screenshot_fd_in,
                                         bool is_screenshot_requested) {
     // Duplicate the fds because the passed in fds don't outlive the binder transaction.
-    bugreport_fd.reset(dup(bugreport_fd_in.get()));
-    screenshot_fd.reset(dup(screenshot_fd_in.get()));
+    bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0));
+    screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0));
 
     SetOptionsFromMode(bugreport_mode, this, is_screenshot_requested);
 }
diff --git a/include/ftl/Flags.h b/include/ftl/Flags.h
index 708eaf5..db3d9ea 100644
--- a/include/ftl/Flags.h
+++ b/include/ftl/Flags.h
@@ -19,13 +19,12 @@
 #include <ftl/enum.h>
 #include <ftl/string.h>
 
+#include <bitset>
 #include <cstdint>
 #include <iterator>
 #include <string>
 #include <type_traits>
 
-#include "utils/BitSet.h"
-
 // TODO(b/185536303): Align with FTL style and namespace.
 
 namespace android {
@@ -56,21 +55,22 @@
           : mFlags(t) {}
 
     class Iterator {
-        // The type can't be larger than 64-bits otherwise it won't fit in BitSet64.
-        static_assert(sizeof(U) <= sizeof(uint64_t));
+        using Bits = std::uint64_t;
+        static_assert(sizeof(U) <= sizeof(Bits));
 
     public:
+        constexpr Iterator() = default;
         Iterator(Flags<F> flags) : mRemainingFlags(flags.mFlags) { (*this)++; }
-        Iterator() : mRemainingFlags(0), mCurrFlag(static_cast<F>(0)) {}
 
         // Pre-fix ++
         Iterator& operator++() {
-            if (mRemainingFlags.isEmpty()) {
-                mCurrFlag = static_cast<F>(0);
+            if (mRemainingFlags.none()) {
+                mCurrFlag = 0;
             } else {
-                uint64_t bit = mRemainingFlags.clearLastMarkedBit(); // counts from left
-                const U flag = 1 << (64 - bit - 1);
-                mCurrFlag = static_cast<F>(flag);
+                // TODO: Replace with std::countr_zero in C++20.
+                const Bits bit = static_cast<Bits>(__builtin_ctzll(mRemainingFlags.to_ullong()));
+                mRemainingFlags.reset(static_cast<std::size_t>(bit));
+                mCurrFlag = static_cast<U>(static_cast<Bits>(1) << bit);
             }
             return *this;
         }
@@ -88,7 +88,7 @@
 
         bool operator!=(Iterator other) const { return !(*this == other); }
 
-        F operator*() { return mCurrFlag; }
+        F operator*() const { return F{mCurrFlag}; }
 
         // iterator traits
 
@@ -107,8 +107,8 @@
         using pointer = void;
 
     private:
-        BitSet64 mRemainingFlags;
-        F mCurrFlag;
+        std::bitset<sizeof(Bits) * 8> mRemainingFlags;
+        U mCurrFlag = 0;
     };
 
     /*
diff --git a/include/ftl/enum.h b/include/ftl/enum.h
index 5234c05..82af1d6 100644
--- a/include/ftl/enum.h
+++ b/include/ftl/enum.h
@@ -261,10 +261,10 @@
   const auto value = to_underlying(v);
 
   // TODO: Replace with std::popcount and std::countr_zero in C++20.
-  if (__builtin_popcountl(value) != 1) return {};
+  if (__builtin_popcountll(value) != 1) return {};
 
   constexpr auto kRange = details::EnumRange<E, details::FlagName>{};
-  return kRange.values[__builtin_ctzl(value)];
+  return kRange.values[__builtin_ctzll(value)];
 }
 
 // Returns a stringified enumerator, or its integral value if not named.
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index 97b522a..ef20196 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -32,12 +32,4 @@
         "-Wpedantic",
         "-Wthread-safety",
     ],
-
-    header_libs: [
-        "libbase_headers",
-    ],
-
-    shared_libs: [
-        "libbase",
-    ],
 }
diff --git a/libs/ftl/enum_test.cpp b/libs/ftl/enum_test.cpp
index d8ce7a5..5592a01 100644
--- a/libs/ftl/enum_test.cpp
+++ b/libs/ftl/enum_test.cpp
@@ -143,6 +143,16 @@
     EXPECT_EQ(ftl::flag_string(Flags::kNone), "0b0");
     EXPECT_EQ(ftl::flag_string(Flags::kMask), "0b10010010");
     EXPECT_EQ(ftl::flag_string(Flags::kAll), "0b11111111");
+
+    enum class Flags64 : std::uint64_t {
+      kFlag0 = 0b1ull,
+      kFlag63 = 0x8000'0000'0000'0000ull,
+      kMask = kFlag0 | kFlag63
+    };
+
+    EXPECT_EQ(ftl::flag_string(Flags64::kFlag0), "kFlag0");
+    EXPECT_EQ(ftl::flag_string(Flags64::kFlag63), "kFlag63");
+    EXPECT_EQ(ftl::flag_string(Flags64::kMask), "0x8000000000000001");
   }
   {
     EXPECT_EQ(ftl::enum_string(Planet::kEarth), "kEarth");
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index a6465ee..7f427f2 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -15,13 +15,6 @@
  */
 
 #define LOG_TAG "VelocityTracker"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about velocity tracking.
-static constexpr bool DEBUG_VELOCITY = false;
-
-// Log debug messages about the progress of the algorithm itself.
-static constexpr bool DEBUG_STRATEGY = false;
 
 #include <array>
 #include <inttypes.h>
@@ -36,6 +29,27 @@
 
 namespace android {
 
+/**
+ * Log debug messages about velocity tracking.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerVelocity DEBUG" (requires restart)
+ */
+const bool DEBUG_VELOCITY =
+        __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Velocity", ANDROID_LOG_INFO);
+
+/**
+ * Log debug messages about the progress of the algorithm itself.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerStrategy DEBUG" (requires restart)
+ */
+const bool DEBUG_STRATEGY =
+        __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Strategy", ANDROID_LOG_INFO);
+
+/**
+ * Log debug messages about the 'impulse' strategy.
+ * Enable this via "adb shell setprop log.tag.VelocityTrackerImpulse DEBUG" (requires restart)
+ */
+const bool DEBUG_IMPULSE =
+        __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Impulse", ANDROID_LOG_INFO);
+
 // Nanoseconds per milliseconds.
 static const nsecs_t NANOS_PER_MS = 1000000;
 
@@ -141,7 +155,7 @@
             return std::make_unique<LeastSquaresVelocityTrackerStrategy>(1);
 
         case VelocityTracker::Strategy::LSQ2:
-            if (DEBUG_STRATEGY) {
+            if (DEBUG_STRATEGY && !DEBUG_IMPULSE) {
                 ALOGI("Initializing lsq2 strategy");
             }
             return std::make_unique<LeastSquaresVelocityTrackerStrategy>(2);
@@ -1172,7 +1186,25 @@
     outEstimator->degree = 2; // similar results to 2nd degree fit
     outEstimator->confidence = 1;
     if (DEBUG_STRATEGY) {
-        ALOGD("velocity: (%f, %f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
+        ALOGD("velocity: (%.1f, %.1f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
+    }
+    if (DEBUG_IMPULSE) {
+        // TODO(b/134179997): delete this block once the switch to 'impulse' is complete.
+        // Calculate the lsq2 velocity for the same inputs to allow runtime comparisons
+        VelocityTracker lsq2(VelocityTracker::Strategy::LSQ2);
+        BitSet32 idBits;
+        const uint32_t pointerId = 0;
+        idBits.markBit(pointerId);
+        for (ssize_t i = m - 1; i >= 0; i--) {
+            lsq2.addMovement(time[i], idBits, {{x[i], y[i]}});
+        }
+        float outVx = 0, outVy = 0;
+        const bool computed = lsq2.getVelocity(pointerId, &outVx, &outVy);
+        if (computed) {
+            ALOGD("lsq2 velocity: (%.1f, %.1f)", outVx, outVy);
+        } else {
+            ALOGD("lsq2 velocity: could not compute velocity");
+        }
     }
     return true;
 }