1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <android/choreographer.h> 20 #include <gui/DisplayEventDispatcher.h> 21 #include <jni.h> 22 #include <utils/Looper.h> 23 24 #include <mutex> 25 #include <queue> 26 #include <thread> 27 28 namespace android { 29 using gui::VsyncEventData; 30 31 struct FrameCallback { 32 AChoreographer_frameCallback callback; 33 AChoreographer_frameCallback64 callback64; 34 AChoreographer_vsyncCallback vsyncCallback; 35 void* data; 36 nsecs_t dueTime; 37 38 inline bool operator<(const FrameCallback& rhs) const { 39 // Note that this is intentionally flipped because we want callbacks due sooner to be at 40 // the head of the queue 41 return dueTime > rhs.dueTime; 42 } 43 }; 44 45 struct RefreshRateCallback { 46 AChoreographer_refreshRateCallback callback; 47 void* data; 48 bool firstCallbackFired = false; 49 }; 50 51 class Choreographer; 52 53 /** 54 * Implementation of AChoreographerFrameCallbackData. 55 */ 56 struct ChoreographerFrameCallbackDataImpl { 57 int64_t frameTimeNanos{0}; 58 59 VsyncEventData vsyncEventData; 60 61 const Choreographer* choreographer; 62 }; 63 64 class Choreographer : public DisplayEventDispatcher, public MessageHandler { 65 public: 66 struct Context { 67 std::mutex lock; 68 std::vector<Choreographer*> ptrs GUARDED_BY(lock); 69 std::map<AVsyncId, int64_t> startTimes GUARDED_BY(lock); 70 bool registeredToDisplayManager GUARDED_BY(lock) = false; 71 72 std::atomic<nsecs_t> mLastKnownVsync = -1; 73 }; 74 static Context gChoreographers; 75 76 explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle = nullptr) 77 EXCLUDES(gChoreographers.lock); 78 void postFrameCallbackDelayed(AChoreographer_frameCallback cb, 79 AChoreographer_frameCallback64 cb64, 80 AChoreographer_vsyncCallback vsyncCallback, void* data, 81 nsecs_t delay); 82 void registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data) 83 EXCLUDES(gChoreographers.lock); 84 void unregisterRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data); 85 // Drains the queue of pending vsync periods and dispatches refresh rate 86 // updates to callbacks. 87 // The assumption is that this method is only called on a single 88 // processing thread, either by looper or by AChoreographer_handleEvents 89 void handleRefreshRateUpdates(); 90 void scheduleLatestConfigRequest(); 91 92 enum { 93 MSG_SCHEDULE_CALLBACKS = 0, 94 MSG_SCHEDULE_VSYNC = 1, 95 MSG_HANDLE_REFRESH_RATE_UPDATES = 2, 96 }; 97 virtual void handleMessage(const Message& message) override; 98 99 static void initJVM(JNIEnv* env); 100 static Choreographer* getForThread(); 101 static void signalRefreshRateCallbacks(nsecs_t vsyncPeriod) EXCLUDES(gChoreographers.lock); 102 static int64_t getStartTimeNanosForVsyncId(AVsyncId vsyncId) EXCLUDES(gChoreographers.lock); 103 virtual ~Choreographer() override EXCLUDES(gChoreographers.lock); 104 int64_t getFrameInterval() const; 105 bool inCallback() const; 106 107 private: 108 Choreographer(const Choreographer&) = delete; 109 110 void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, 111 VsyncEventData vsyncEventData) override; 112 void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override; 113 void dispatchModeChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId, 114 nsecs_t vsyncPeriod) override; 115 void dispatchNullEvent(nsecs_t, PhysicalDisplayId) override; 116 void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId, 117 std::vector<FrameRateOverride> overrides) override; 118 119 void scheduleCallbacks(); 120 121 ChoreographerFrameCallbackDataImpl createFrameCallbackData(nsecs_t timestamp) const; 122 void registerStartTime() const; 123 124 std::mutex mLock; 125 // Protected by mLock 126 std::priority_queue<FrameCallback> mFrameCallbacks; 127 std::vector<RefreshRateCallback> mRefreshRateCallbacks; 128 129 nsecs_t mLatestVsyncPeriod = -1; 130 VsyncEventData mLastVsyncEventData; 131 bool mInCallback = false; 132 133 const sp<Looper> mLooper; 134 const std::thread::id mThreadId; 135 136 // Approximation of num_threads_using_choreographer * num_frames_of_history with leeway. 137 static constexpr size_t kMaxStartTimes = 250; 138 }; 139 140 } // namespace android