1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2019 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 20*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/IRegionSamplingListener.h> 21*38e8c45fSAndroid Build Coastguard Worker #include <binder/IBinder.h> 22*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/ExternalTexture.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h> 24*38e8c45fSAndroid Build Coastguard Worker #include <ui/Rect.h> 25*38e8c45fSAndroid Build Coastguard Worker #include <utils/StrongPointer.h> 26*38e8c45fSAndroid Build Coastguard Worker 27*38e8c45fSAndroid Build Coastguard Worker #include <chrono> 28*38e8c45fSAndroid Build Coastguard Worker #include <condition_variable> 29*38e8c45fSAndroid Build Coastguard Worker #include <cstdint> 30*38e8c45fSAndroid Build Coastguard Worker #include <mutex> 31*38e8c45fSAndroid Build Coastguard Worker #include <thread> 32*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map> 33*38e8c45fSAndroid Build Coastguard Worker 34*38e8c45fSAndroid Build Coastguard Worker #include "Scheduler/OneShotTimer.h" 35*38e8c45fSAndroid Build Coastguard Worker #include "WpHash.h" 36*38e8c45fSAndroid Build Coastguard Worker 37*38e8c45fSAndroid Build Coastguard Worker namespace android { 38*38e8c45fSAndroid Build Coastguard Worker 39*38e8c45fSAndroid Build Coastguard Worker class Layer; 40*38e8c45fSAndroid Build Coastguard Worker class SurfaceFlinger; 41*38e8c45fSAndroid Build Coastguard Worker struct SamplingOffsetCallback; 42*38e8c45fSAndroid Build Coastguard Worker 43*38e8c45fSAndroid Build Coastguard Worker using gui::IRegionSamplingListener; 44*38e8c45fSAndroid Build Coastguard Worker 45*38e8c45fSAndroid Build Coastguard Worker float sampleArea(const uint32_t* data, int32_t width, int32_t height, int32_t stride, 46*38e8c45fSAndroid Build Coastguard Worker uint32_t orientation, const Rect& area); 47*38e8c45fSAndroid Build Coastguard Worker 48*38e8c45fSAndroid Build Coastguard Worker class RegionSamplingThread : public IBinder::DeathRecipient { 49*38e8c45fSAndroid Build Coastguard Worker public: 50*38e8c45fSAndroid Build Coastguard Worker struct TimingTunables { 51*38e8c45fSAndroid Build Coastguard Worker // debug.sf.sampling_duration_ns 52*38e8c45fSAndroid Build Coastguard Worker // When asynchronously collecting sample, the duration, at which the sampling should start 53*38e8c45fSAndroid Build Coastguard Worker // before a vsync 54*38e8c45fSAndroid Build Coastguard Worker std::chrono::nanoseconds mSamplingDuration; 55*38e8c45fSAndroid Build Coastguard Worker // debug.sf.sampling_period_ns 56*38e8c45fSAndroid Build Coastguard Worker // This is the maximum amount of time the luma recieving client 57*38e8c45fSAndroid Build Coastguard Worker // should have to wait for a new luma value after a frame is updated. The inverse of this is 58*38e8c45fSAndroid Build Coastguard Worker // roughly the sampling rate. Sampling system rounds up sub-vsync sampling period to vsync 59*38e8c45fSAndroid Build Coastguard Worker // period. 60*38e8c45fSAndroid Build Coastguard Worker std::chrono::nanoseconds mSamplingPeriod; 61*38e8c45fSAndroid Build Coastguard Worker // debug.sf.sampling_timer_timeout_ns 62*38e8c45fSAndroid Build Coastguard Worker // This is the interval at which the luma sampling system will check that the luma clients 63*38e8c45fSAndroid Build Coastguard Worker // have up to date information. It defaults to the mSamplingPeriod. 64*38e8c45fSAndroid Build Coastguard Worker std::chrono::nanoseconds mSamplingTimerTimeout; 65*38e8c45fSAndroid Build Coastguard Worker }; 66*38e8c45fSAndroid Build Coastguard Worker struct EnvironmentTimingTunables : TimingTunables { 67*38e8c45fSAndroid Build Coastguard Worker EnvironmentTimingTunables(); 68*38e8c45fSAndroid Build Coastguard Worker }; 69*38e8c45fSAndroid Build Coastguard Worker explicit RegionSamplingThread(SurfaceFlinger& flinger, const TimingTunables& tunables); 70*38e8c45fSAndroid Build Coastguard Worker explicit RegionSamplingThread(SurfaceFlinger& flinger); 71*38e8c45fSAndroid Build Coastguard Worker 72*38e8c45fSAndroid Build Coastguard Worker ~RegionSamplingThread(); 73*38e8c45fSAndroid Build Coastguard Worker 74*38e8c45fSAndroid Build Coastguard Worker // Add a listener to receive luma notifications. The luma reported via listener will 75*38e8c45fSAndroid Build Coastguard Worker // report the median luma for the layers under the stopLayerHandle, in the samplingArea region. 76*38e8c45fSAndroid Build Coastguard Worker void addListener(const Rect& samplingArea, uint32_t stopLayerId, 77*38e8c45fSAndroid Build Coastguard Worker const sp<IRegionSamplingListener>& listener); 78*38e8c45fSAndroid Build Coastguard Worker // Remove the listener to stop receiving median luma notifications. 79*38e8c45fSAndroid Build Coastguard Worker void removeListener(const sp<IRegionSamplingListener>& listener); 80*38e8c45fSAndroid Build Coastguard Worker 81*38e8c45fSAndroid Build Coastguard Worker // Notifies sampling engine that composition is done and new content is 82*38e8c45fSAndroid Build Coastguard Worker // available, and the deadline for the sampling work on the main thread to 83*38e8c45fSAndroid Build Coastguard Worker // be completed without eating the budget of another frame. 84*38e8c45fSAndroid Build Coastguard Worker void onCompositionComplete( 85*38e8c45fSAndroid Build Coastguard Worker std::optional<std::chrono::steady_clock::time_point> samplingDeadline); 86*38e8c45fSAndroid Build Coastguard Worker 87*38e8c45fSAndroid Build Coastguard Worker private: 88*38e8c45fSAndroid Build Coastguard Worker struct Descriptor { 89*38e8c45fSAndroid Build Coastguard Worker Rect area = Rect::EMPTY_RECT; 90*38e8c45fSAndroid Build Coastguard Worker uint32_t stopLayerId; 91*38e8c45fSAndroid Build Coastguard Worker sp<IRegionSamplingListener> listener; 92*38e8c45fSAndroid Build Coastguard Worker }; 93*38e8c45fSAndroid Build Coastguard Worker 94*38e8c45fSAndroid Build Coastguard Worker std::vector<float> sampleBuffer( 95*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& buffer, const Point& leftTop, 96*38e8c45fSAndroid Build Coastguard Worker const std::vector<RegionSamplingThread::Descriptor>& descriptors, uint32_t orientation); 97*38e8c45fSAndroid Build Coastguard Worker 98*38e8c45fSAndroid Build Coastguard Worker void doSample(std::optional<std::chrono::steady_clock::time_point> samplingDeadline); 99*38e8c45fSAndroid Build Coastguard Worker void binderDied(const wp<IBinder>& who) override; 100*38e8c45fSAndroid Build Coastguard Worker void checkForStaleLuma(); 101*38e8c45fSAndroid Build Coastguard Worker 102*38e8c45fSAndroid Build Coastguard Worker void captureSample(); 103*38e8c45fSAndroid Build Coastguard Worker void threadMain(); 104*38e8c45fSAndroid Build Coastguard Worker 105*38e8c45fSAndroid Build Coastguard Worker SurfaceFlinger& mFlinger; 106*38e8c45fSAndroid Build Coastguard Worker const TimingTunables mTunables; 107*38e8c45fSAndroid Build Coastguard Worker scheduler::OneShotTimer mIdleTimer; 108*38e8c45fSAndroid Build Coastguard Worker 109*38e8c45fSAndroid Build Coastguard Worker std::thread mThread; 110*38e8c45fSAndroid Build Coastguard Worker 111*38e8c45fSAndroid Build Coastguard Worker std::mutex mThreadControlMutex; 112*38e8c45fSAndroid Build Coastguard Worker std::condition_variable_any mCondition; 113*38e8c45fSAndroid Build Coastguard Worker bool mRunning GUARDED_BY(mThreadControlMutex) = true; 114*38e8c45fSAndroid Build Coastguard Worker bool mSampleRequested GUARDED_BY(mThreadControlMutex) = false; 115*38e8c45fSAndroid Build Coastguard Worker std::optional<std::chrono::steady_clock::time_point> mSampleRequestTime 116*38e8c45fSAndroid Build Coastguard Worker GUARDED_BY(mThreadControlMutex); 117*38e8c45fSAndroid Build Coastguard Worker std::chrono::steady_clock::time_point mLastSampleTime GUARDED_BY(mThreadControlMutex); 118*38e8c45fSAndroid Build Coastguard Worker 119*38e8c45fSAndroid Build Coastguard Worker std::mutex mSamplingMutex; 120*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex); 121*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<renderengine::ExternalTexture> mCachedBuffer GUARDED_BY(mSamplingMutex) = 122*38e8c45fSAndroid Build Coastguard Worker nullptr; 123*38e8c45fSAndroid Build Coastguard Worker }; 124*38e8c45fSAndroid Build Coastguard Worker 125*38e8c45fSAndroid Build Coastguard Worker } // namespace android 126