| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2019 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 |  | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 19 | #include <android-base/thread_annotations.h> | 
|  | 20 | #include <binder/IBinder.h> | 
|  | 21 | #include <renderengine/ExternalTexture.h> | 
|  | 22 | #include <ui/GraphicBuffer.h> | 
|  | 23 | #include <ui/Rect.h> | 
|  | 24 | #include <utils/StrongPointer.h> | 
|  | 25 |  | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 26 | #include <chrono> | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 27 | #include <condition_variable> | 
|  | 28 | #include <mutex> | 
|  | 29 | #include <thread> | 
|  | 30 | #include <unordered_map> | 
|  | 31 |  | 
| Ana Krulec | f2c006d | 2019-06-21 15:37:07 -0700 | [diff] [blame] | 32 | #include "Scheduler/OneShotTimer.h" | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 33 |  | 
|  | 34 | namespace android { | 
|  | 35 |  | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 36 | class IRegionSamplingListener; | 
|  | 37 | class Layer; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 38 | class Scheduler; | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 39 | class SurfaceFlinger; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 40 | struct SamplingOffsetCallback; | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 41 |  | 
| Kevin DuBois | b325c93 | 2019-05-21 08:34:09 -0700 | [diff] [blame] | 42 | float sampleArea(const uint32_t* data, int32_t width, int32_t height, int32_t stride, | 
|  | 43 | uint32_t orientation, const Rect& area); | 
| Kevin DuBois | bb27bcd | 2019-04-02 14:34:35 -0700 | [diff] [blame] | 44 |  | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 45 | class RegionSamplingThread : public IBinder::DeathRecipient { | 
|  | 46 | public: | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 47 | struct TimingTunables { | 
| Ady Abraham | 9c53ee7 | 2020-07-22 21:16:18 -0700 | [diff] [blame] | 48 | // debug.sf.sampling_duration_ns | 
|  | 49 | // When asynchronously collecting sample, the duration, at which the sampling should start | 
|  | 50 | // before a vsync | 
|  | 51 | std::chrono::nanoseconds mSamplingDuration; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 52 | // debug.sf.sampling_period_ns | 
|  | 53 | // This is the maximum amount of time the luma recieving client | 
|  | 54 | // should have to wait for a new luma value after a frame is updated. The inverse of this is | 
|  | 55 | // roughly the sampling rate. Sampling system rounds up sub-vsync sampling period to vsync | 
|  | 56 | // period. | 
|  | 57 | std::chrono::nanoseconds mSamplingPeriod; | 
|  | 58 | // debug.sf.sampling_timer_timeout_ns | 
|  | 59 | // This is the interval at which the luma sampling system will check that the luma clients | 
|  | 60 | // have up to date information. It defaults to the mSamplingPeriod. | 
|  | 61 | std::chrono::nanoseconds mSamplingTimerTimeout; | 
|  | 62 | }; | 
|  | 63 | struct EnvironmentTimingTunables : TimingTunables { | 
|  | 64 | EnvironmentTimingTunables(); | 
|  | 65 | }; | 
| Ady Abraham | 562c271 | 2021-05-07 15:10:42 -0700 | [diff] [blame] | 66 | explicit RegionSamplingThread(SurfaceFlinger& flinger, const TimingTunables& tunables); | 
|  | 67 | explicit RegionSamplingThread(SurfaceFlinger& flinger); | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 68 |  | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 69 | ~RegionSamplingThread(); | 
|  | 70 |  | 
| Kevin DuBois | 7cbcc37 | 2019-02-25 14:53:28 -0800 | [diff] [blame] | 71 | // Add a listener to receive luma notifications. The luma reported via listener will | 
|  | 72 | // report the median luma for the layers under the stopLayerHandle, in the samplingArea region. | 
| Alec Mouri | 9a02eda | 2020-04-21 17:39:34 -0700 | [diff] [blame] | 73 | void addListener(const Rect& samplingArea, const wp<Layer>& stopLayer, | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 74 | const sp<IRegionSamplingListener>& listener); | 
| Kevin DuBois | 7cbcc37 | 2019-02-25 14:53:28 -0800 | [diff] [blame] | 75 | // Remove the listener to stop receiving median luma notifications. | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 76 | void removeListener(const sp<IRegionSamplingListener>& listener); | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 77 |  | 
| Ady Abraham | 562c271 | 2021-05-07 15:10:42 -0700 | [diff] [blame] | 78 | // Notifies sampling engine that composition is done and new content is | 
|  | 79 | // available, and the deadline for the sampling work on the main thread to | 
|  | 80 | // be completed without eating the budget of another frame. | 
|  | 81 | void onCompositionComplete( | 
|  | 82 | std::optional<std::chrono::steady_clock::time_point> samplingDeadline); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 83 |  | 
| Kevin DuBois | 7cbcc37 | 2019-02-25 14:53:28 -0800 | [diff] [blame] | 84 | private: | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 85 | struct Descriptor { | 
|  | 86 | Rect area = Rect::EMPTY_RECT; | 
|  | 87 | wp<Layer> stopLayer; | 
|  | 88 | sp<IRegionSamplingListener> listener; | 
|  | 89 | }; | 
|  | 90 |  | 
|  | 91 | struct WpHash { | 
|  | 92 | size_t operator()(const wp<IBinder>& p) const { | 
|  | 93 | return std::hash<IBinder*>()(p.unsafe_get()); | 
|  | 94 | } | 
|  | 95 | }; | 
| Kevin DuBois | 7cbcc37 | 2019-02-25 14:53:28 -0800 | [diff] [blame] | 96 | std::vector<float> sampleBuffer( | 
|  | 97 | const sp<GraphicBuffer>& buffer, const Point& leftTop, | 
| Kevin DuBois | b325c93 | 2019-05-21 08:34:09 -0700 | [diff] [blame] | 98 | const std::vector<RegionSamplingThread::Descriptor>& descriptors, uint32_t orientation); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 99 |  | 
| Ady Abraham | 562c271 | 2021-05-07 15:10:42 -0700 | [diff] [blame] | 100 | void doSample(std::optional<std::chrono::steady_clock::time_point> samplingDeadline); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 101 | void binderDied(const wp<IBinder>& who) override; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 102 | void checkForStaleLuma(); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 103 |  | 
| Kevin DuBois | 26afc78 | 2019-05-06 16:46:45 -0700 | [diff] [blame] | 104 | void captureSample(); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 105 | void threadMain(); | 
|  | 106 |  | 
|  | 107 | SurfaceFlinger& mFlinger; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 108 | const TimingTunables mTunables; | 
| Ana Krulec | f2c006d | 2019-06-21 15:37:07 -0700 | [diff] [blame] | 109 | scheduler::OneShotTimer mIdleTimer; | 
| Kevin DuBois | 413287f | 2019-02-25 08:46:47 -0800 | [diff] [blame] | 110 |  | 
| Kevin DuBois | 26afc78 | 2019-05-06 16:46:45 -0700 | [diff] [blame] | 111 | std::thread mThread; | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 112 |  | 
| Kevin DuBois | 26afc78 | 2019-05-06 16:46:45 -0700 | [diff] [blame] | 113 | std::mutex mThreadControlMutex; | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 114 | std::condition_variable_any mCondition; | 
| Kevin DuBois | 26afc78 | 2019-05-06 16:46:45 -0700 | [diff] [blame] | 115 | bool mRunning GUARDED_BY(mThreadControlMutex) = true; | 
|  | 116 | bool mSampleRequested GUARDED_BY(mThreadControlMutex) = false; | 
| Ady Abraham | 562c271 | 2021-05-07 15:10:42 -0700 | [diff] [blame] | 117 | std::optional<std::chrono::steady_clock::time_point> mSampleRequestTime | 
|  | 118 | GUARDED_BY(mThreadControlMutex); | 
|  | 119 | std::chrono::steady_clock::time_point mLastSampleTime GUARDED_BY(mThreadControlMutex); | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 120 |  | 
| Kevin DuBois | 26afc78 | 2019-05-06 16:46:45 -0700 | [diff] [blame] | 121 | std::mutex mSamplingMutex; | 
|  | 122 | std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex); | 
| Alec Mouri | a90a570 | 2021-04-16 16:36:21 +0000 | [diff] [blame] | 123 | std::shared_ptr<renderengine::ExternalTexture> mCachedBuffer GUARDED_BY(mSamplingMutex) = | 
|  | 124 | nullptr; | 
| Dan Stoza | ec46008 | 2018-12-17 15:35:09 -0800 | [diff] [blame] | 125 | }; | 
|  | 126 |  | 
|  | 127 | } // namespace android |