Merge "Fix callback registration during merging in same-process"
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c7eb9c3..6fd1629 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1930,6 +1930,11 @@
                                        [&]() { return layerInfo->mutable_visible_region(); });
         LayerProtoHelper::writeToProto(surfaceDamageRegion,
                                        [&]() { return layerInfo->mutable_damage_region(); });
+
+        if (hasColorTransform()) {
+            LayerProtoHelper::writeToProto(getColorTransform(),
+                                           layerInfo->mutable_color_transform());
+        }
     }
 
     if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index c94e439..b402270 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -155,5 +155,13 @@
     }
 }
 
+void LayerProtoHelper::writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto) {
+    for (int i = 0; i < mat4::ROW_SIZE; i++) {
+        for (int j = 0; j < mat4::COL_SIZE; j++) {
+            colorTransformProto->add_val(matrix[i][j]);
+        }
+    }
+}
+
 } // namespace surfaceflinger
 } // namespace android
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 1754a3f..502238d 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -43,6 +43,7 @@
     static void writeToProto(const InputWindowInfo& inputInfo,
                              const wp<Layer>& touchableRegionBounds,
                              std::function<InputWindowInfoProto*()> getInputWindowInfoProto);
+    static void writeToProto(const mat4 matrix, ColorTransformProto* colorTransformProto);
 };
 
 } // namespace surfaceflinger
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 71ebfc3..e845e8c 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -47,6 +47,10 @@
 #include "OneShotTimer.h"
 #include "SchedulerUtils.h"
 #include "SurfaceFlingerProperties.h"
+#include "Timer.h"
+#include "VSyncDispatchTimerQueue.h"
+#include "VSyncPredictor.h"
+#include "VSyncReactor.h"
 
 #define RETURN_IF_INVALID_HANDLE(handle, ...)                        \
     do {                                                             \
@@ -58,11 +62,45 @@
 
 namespace android {
 
+std::unique_ptr<DispSync> createDispSync() {
+    // TODO (140302863) remove this and use the vsync_reactor system.
+    if (property_get_bool("debug.sf.vsync_reactor", false)) {
+        // TODO (144707443) tune Predictor tunables.
+        static constexpr int default_rate = 60;
+        static constexpr auto initial_period =
+                std::chrono::duration<nsecs_t, std::ratio<1, default_rate>>(1);
+        static constexpr size_t vsyncTimestampHistorySize = 20;
+        static constexpr size_t minimumSamplesForPrediction = 6;
+        static constexpr uint32_t discardOutlierPercent = 20;
+        auto tracker = std::make_unique<
+                scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>(
+                                                   initial_period)
+                                                   .count(),
+                                           vsyncTimestampHistorySize, minimumSamplesForPrediction,
+                                           discardOutlierPercent);
+
+        static constexpr auto vsyncMoveThreshold =
+                std::chrono::duration_cast<std::chrono::nanoseconds>(3ms);
+        static constexpr auto timerSlack =
+                std::chrono::duration_cast<std::chrono::nanoseconds>(500us);
+        auto dispatch = std::make_unique<
+                scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), *tracker,
+                                                    timerSlack.count(), vsyncMoveThreshold.count());
+
+        static constexpr size_t pendingFenceLimit = 20;
+        return std::make_unique<scheduler::VSyncReactor>(std::make_unique<scheduler::SystemClock>(),
+                                                         std::move(dispatch), std::move(tracker),
+                                                         pendingFenceLimit);
+    } else {
+        return std::make_unique<impl::DispSync>("SchedulerDispSync",
+                                                sysprop::running_without_sync_framework(true));
+    }
+}
+
 Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
                      const scheduler::RefreshRateConfigs& refreshRateConfig,
                      ISchedulerCallback& schedulerCallback)
-      : mPrimaryDispSync(new impl::DispSync("SchedulerDispSync",
-                                            sysprop::running_without_sync_framework(true))),
+      : mPrimaryDispSync(createDispSync()),
         mEventControlThread(new impl::EventControlThread(std::move(function))),
         mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
         mSchedulerCallback(schedulerCallback),
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 47e3f4f..c471e49 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -26,12 +26,15 @@
 namespace android::scheduler {
 
 Clock::~Clock() = default;
+nsecs_t SystemClock::now() const {
+    return systemTime(SYSTEM_TIME_MONOTONIC);
+}
 
 VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
                            std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
       : mClock(std::move(clock)),
-        mDispatch(std::move(dispatch)),
         mTracker(std::move(tracker)),
+        mDispatch(std::move(dispatch)),
         mPendingLimit(pendingFenceLimit) {}
 
 VSyncReactor::~VSyncReactor() = default;
@@ -245,4 +248,10 @@
     return NO_ERROR;
 }
 
+void VSyncReactor::dump(std::string& result) const {
+    result += "VsyncReactor in use\n"; // TODO (b/144927823): add more information!
+}
+
+void VSyncReactor::reset() {}
+
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 837eb75..29a0a11 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -23,7 +23,7 @@
 #include <unordered_map>
 #include <vector>
 #include "DispSync.h"
-
+#include "TimeKeeper.h"
 namespace android::scheduler {
 
 class Clock;
@@ -32,35 +32,38 @@
 class CallbackRepeater;
 
 // TODO (b/145217110): consider renaming.
-class VSyncReactor /* TODO (b/140201379): : public android::DispSync */ {
+class VSyncReactor : public android::DispSync {
 public:
     VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
                  std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit);
     ~VSyncReactor();
 
-    bool addPresentFence(const std::shared_ptr<FenceTime>& fence);
-    void setIgnorePresentFences(bool ignoration);
+    bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
+    void setIgnorePresentFences(bool ignoration) final;
 
-    nsecs_t computeNextRefresh(int periodOffset) const;
-    nsecs_t expectedPresentTime();
+    nsecs_t computeNextRefresh(int periodOffset) const final;
+    nsecs_t expectedPresentTime() final;
 
-    void setPeriod(nsecs_t period);
-    nsecs_t getPeriod();
+    void setPeriod(nsecs_t period) final;
+    nsecs_t getPeriod() final;
 
     // TODO: (b/145626181) remove begin,endResync functions from DispSync i/f when possible.
-    void beginResync();
-    bool addResyncSample(nsecs_t timestamp, bool* periodFlushed);
-    void endResync();
+    void beginResync() final;
+    bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) final;
+    void endResync() final;
 
     status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback,
-                              nsecs_t lastCallbackTime);
-    status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback);
-    status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase);
+                              nsecs_t lastCallbackTime) final;
+    status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback) final;
+    status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase) final;
+
+    void dump(std::string& result) const final;
+    void reset() final;
 
 private:
     std::unique_ptr<Clock> const mClock;
-    std::unique_ptr<VSyncDispatch> const mDispatch;
     std::unique_ptr<VSyncTracker> const mTracker;
+    std::unique_ptr<VSyncDispatch> const mDispatch;
     size_t const mPendingLimit;
 
     std::mutex mMutex;
@@ -71,4 +74,8 @@
             GUARDED_BY(mMutex);
 };
 
+class SystemClock : public Clock {
+    nsecs_t now() const final;
+};
+
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 9ad9b91..23df1bb 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -101,6 +101,7 @@
   // length of the shadow to draw around the layer, it may be set on the
   // layer or set by a parent layer.
   float shadow_radius = 49;
+  ColorTransformProto color_transform = 50;
 }
 
 message PositionProto {
@@ -181,3 +182,8 @@
     bool replace_touchable_region_with_crop = 14;
     RectProto touchable_region_crop = 15;
 }
+
+message ColorTransformProto {
+  // This will be a 4x4 matrix of float values
+  repeated float val = 1;
+}
\ No newline at end of file