RegionSamplingThread.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. #pragma once
  17. #include <chrono>
  18. #include <condition_variable>
  19. #include <mutex>
  20. #include <thread>
  21. #include <unordered_map>
  22. #include <android-base/thread_annotations.h>
  23. #include <binder/IBinder.h>
  24. #include <ui/GraphicBuffer.h>
  25. #include <ui/Rect.h>
  26. #include <utils/StrongPointer.h>
  27. #include "Scheduler/IdleTimer.h"
  28. namespace android {
  29. class IRegionSamplingListener;
  30. class Layer;
  31. class Scheduler;
  32. class SurfaceFlinger;
  33. struct SamplingOffsetCallback;
  34. float sampleArea(const uint32_t* data, int32_t width, int32_t height, int32_t stride,
  35. uint32_t orientation, const Rect& area);
  36. class RegionSamplingThread : public IBinder::DeathRecipient {
  37. public:
  38. struct TimingTunables {
  39. // debug.sf.sampling_offset_ns
  40. // When asynchronously collecting sample, the offset, from zero phase in the vsync timeline
  41. // at which the sampling should start.
  42. std::chrono::nanoseconds mSamplingOffset;
  43. // debug.sf.sampling_period_ns
  44. // This is the maximum amount of time the luma recieving client
  45. // should have to wait for a new luma value after a frame is updated. The inverse of this is
  46. // roughly the sampling rate. Sampling system rounds up sub-vsync sampling period to vsync
  47. // period.
  48. std::chrono::nanoseconds mSamplingPeriod;
  49. // debug.sf.sampling_timer_timeout_ns
  50. // This is the interval at which the luma sampling system will check that the luma clients
  51. // have up to date information. It defaults to the mSamplingPeriod.
  52. std::chrono::nanoseconds mSamplingTimerTimeout;
  53. };
  54. struct EnvironmentTimingTunables : TimingTunables {
  55. EnvironmentTimingTunables();
  56. };
  57. explicit RegionSamplingThread(SurfaceFlinger& flinger, Scheduler& scheduler,
  58. const TimingTunables& tunables);
  59. explicit RegionSamplingThread(SurfaceFlinger& flinger, Scheduler& scheduler);
  60. ~RegionSamplingThread();
  61. // Add a listener to receive luma notifications. The luma reported via listener will
  62. // report the median luma for the layers under the stopLayerHandle, in the samplingArea region.
  63. void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
  64. const sp<IRegionSamplingListener>& listener);
  65. // Remove the listener to stop receiving median luma notifications.
  66. void removeListener(const sp<IRegionSamplingListener>& listener);
  67. // Notifies sampling engine that new content is available. This will trigger a sampling
  68. // pass at some point in the future.
  69. void notifyNewContent();
  70. // Notifies the sampling engine that it has a good timing window in which to sample.
  71. void notifySamplingOffset();
  72. private:
  73. struct Descriptor {
  74. Rect area = Rect::EMPTY_RECT;
  75. wp<Layer> stopLayer;
  76. sp<IRegionSamplingListener> listener;
  77. };
  78. struct WpHash {
  79. size_t operator()(const wp<IBinder>& p) const {
  80. return std::hash<IBinder*>()(p.unsafe_get());
  81. }
  82. };
  83. std::vector<float> sampleBuffer(
  84. const sp<GraphicBuffer>& buffer, const Point& leftTop,
  85. const std::vector<RegionSamplingThread::Descriptor>& descriptors, uint32_t orientation);
  86. void doSample();
  87. void binderDied(const wp<IBinder>& who) override;
  88. void checkForStaleLuma();
  89. void captureSample();
  90. void threadMain();
  91. SurfaceFlinger& mFlinger;
  92. Scheduler& mScheduler;
  93. const TimingTunables mTunables;
  94. scheduler::IdleTimer mIdleTimer;
  95. std::unique_ptr<SamplingOffsetCallback> const mPhaseCallback;
  96. std::thread mThread;
  97. std::mutex mThreadControlMutex;
  98. std::condition_variable_any mCondition;
  99. bool mRunning GUARDED_BY(mThreadControlMutex) = true;
  100. bool mSampleRequested GUARDED_BY(mThreadControlMutex) = false;
  101. uint32_t mDiscardedFrames GUARDED_BY(mThreadControlMutex) = 0;
  102. std::chrono::nanoseconds lastSampleTime GUARDED_BY(mThreadControlMutex);
  103. std::mutex mSamplingMutex;
  104. std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex);
  105. sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr;
  106. };
  107. } // namespace android