| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 1 | #ifndef ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_ | 
|  | 2 | #define ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_ | 
|  | 3 |  | 
|  | 4 | #include <log/log.h> | 
|  | 5 | #include <hardware/gralloc.h> | 
|  | 6 | #include <hardware/hardware.h> | 
|  | 7 | #include <hardware/hwcomposer2.h> | 
|  | 8 |  | 
|  | 9 | #include <private/dvr/buffer_hub_client.h> | 
|  | 10 | #include <private/dvr/sync_util.h> | 
|  | 11 |  | 
|  | 12 | #include <array> | 
|  | 13 | #include <condition_variable> | 
|  | 14 | #include <memory> | 
|  | 15 | #include <mutex> | 
|  | 16 | #include <thread> | 
|  | 17 | #include <tuple> | 
|  | 18 | #include <vector> | 
|  | 19 |  | 
|  | 20 | #include <pdx/file_handle.h> | 
|  | 21 | #include <private/dvr/buffer_hub_client.h> | 
|  | 22 | #include <private/dvr/frame_time_history.h> | 
|  | 23 | #include <private/dvr/sync_util.h> | 
|  | 24 |  | 
|  | 25 | #include "acquired_buffer.h" | 
|  | 26 | #include "compositor.h" | 
|  | 27 | #include "display_surface.h" | 
|  | 28 |  | 
|  | 29 | #include "DisplayHardware/ComposerHal.h" | 
|  | 30 |  | 
|  | 31 | // Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing. | 
|  | 32 | #ifndef HWC_TRANSFORM_NONE | 
|  | 33 | #define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0) | 
|  | 34 | #endif | 
|  | 35 |  | 
|  | 36 | namespace android { | 
|  | 37 | namespace dvr { | 
|  | 38 |  | 
|  | 39 | // Basic display metrics for physical displays. Dimensions and densities are | 
|  | 40 | // relative to the physical display orientation, which may be different from the | 
|  | 41 | // logical display orientation exposed to applications. | 
|  | 42 | struct HWCDisplayMetrics { | 
|  | 43 | int width; | 
|  | 44 | int height; | 
|  | 45 | struct { | 
|  | 46 | int x; | 
|  | 47 | int y; | 
|  | 48 | } dpi; | 
|  | 49 | int vsync_period_ns; | 
|  | 50 | }; | 
|  | 51 |  | 
|  | 52 | // Layer represents the connection between a hardware composer layer and the | 
|  | 53 | // source supplying buffers for the layer's contents. | 
|  | 54 | class Layer { | 
|  | 55 | public: | 
|  | 56 | Layer(); | 
|  | 57 |  | 
|  | 58 | // Sets the hardware composer layer and display metrics that this Layer should | 
|  | 59 | // use each Prepare cycle. This class does not own either of these pointers, | 
|  | 60 | // which MUST remain valid for its lifetime. This method MUST be called once | 
|  | 61 | // in the life of the instance before any other method is valid to call. | 
|  | 62 | void Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics); | 
|  | 63 |  | 
|  | 64 | // Releases any shared pointers and fence handles held by this instance. | 
|  | 65 | void Reset(); | 
|  | 66 |  | 
|  | 67 | // Sets up the layer to use a display surface as its content source. The Layer | 
|  | 68 | // will automatically handle ACQUIRE/RELEASE phases for the surface's buffer | 
|  | 69 | // train every frame. | 
|  | 70 | // | 
|  | 71 | // |blending| receives HWC_BLENDING_* values. | 
|  | 72 | // |transform| receives HWC_TRANSFORM_* values. | 
|  | 73 | // |composition_type| receives either HWC_FRAMEBUFFER for most layers or | 
|  | 74 | // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing). | 
|  | 75 | // |index| is the index of this surface in the DisplaySurface array. | 
|  | 76 | void Setup(const std::shared_ptr<DisplaySurface>& surface, | 
|  | 77 | hwc2_blend_mode_t blending, hwc_transform_t transform, | 
|  | 78 | hwc2_composition_t composition_type, size_t index); | 
|  | 79 |  | 
|  | 80 | // Sets up the layer to use a direct buffer as its content source. No special | 
|  | 81 | // handling of the buffer is performed; responsibility for updating or | 
|  | 82 | // changing the buffer each frame is on the caller. | 
|  | 83 | // | 
|  | 84 | // |blending| receives HWC_BLENDING_* values. | 
|  | 85 | // |transform| receives HWC_TRANSFORM_* values. | 
|  | 86 | // |composition_type| receives either HWC_FRAMEBUFFER for most layers or | 
|  | 87 | // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing). | 
|  | 88 | void Setup(const std::shared_ptr<IonBuffer>& buffer, | 
|  | 89 | hwc2_blend_mode_t blending, hwc_transform_t transform, | 
|  | 90 | hwc2_composition_t composition_type, size_t z_order); | 
|  | 91 |  | 
|  | 92 | // Layers that use a direct IonBuffer should call this each frame to update | 
|  | 93 | // which buffer will be used for the next PostLayers. | 
|  | 94 | void UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer); | 
|  | 95 |  | 
|  | 96 | // Sets up the hardware composer layer for the next frame. When the layer is | 
|  | 97 | // associated with a display surface, this method automatically ACQUIRES a new | 
|  | 98 | // buffer if one is available. | 
|  | 99 | void Prepare(); | 
|  | 100 |  | 
|  | 101 | // After calling prepare, if this frame is to be dropped instead of passing | 
|  | 102 | // along to the HWC, call Drop to close the contained fence(s). | 
|  | 103 | void Drop(); | 
|  | 104 |  | 
|  | 105 | // Performs fence bookkeeping after the frame has been posted to hardware | 
|  | 106 | // composer. | 
|  | 107 | void Finish(int release_fence_fd); | 
|  | 108 |  | 
|  | 109 | // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values. | 
|  | 110 | void SetBlending(hwc2_blend_mode_t blending); | 
|  | 111 |  | 
|  | 112 | // Sets the Z-order of this layer | 
|  | 113 | void SetZOrderIndex(int surface_index); | 
|  | 114 |  | 
|  | 115 | // Gets the current IonBuffer associated with this layer. Ownership of the | 
|  | 116 | // buffer DOES NOT pass to the caller and the pointer is not guaranteed to | 
|  | 117 | // remain valid across calls to Layer::Setup(), Layer::Prepare(), or | 
|  | 118 | // Layer::Reset(). YOU HAVE BEEN WARNED. | 
|  | 119 | IonBuffer* GetBuffer(); | 
|  | 120 |  | 
|  | 121 | hwc2_composition_t GetCompositionType() const { return composition_type_; } | 
|  | 122 |  | 
|  | 123 | hwc2_layer_t GetLayerHandle() const { return hardware_composer_layer_; } | 
|  | 124 |  | 
|  | 125 | bool UsesDirectBuffer() const { return direct_buffer_ != nullptr; } | 
|  | 126 |  | 
|  | 127 | bool IsLayerSetup() const { | 
|  | 128 | return direct_buffer_ != nullptr || surface_ != nullptr; | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | // Applies all of the settings to this layer using the hwc functions | 
|  | 132 | void UpdateLayerSettings(); | 
|  | 133 |  | 
|  | 134 | int GetSurfaceId() const { | 
|  | 135 | if (surface_ != nullptr) { | 
|  | 136 | return surface_->surface_id(); | 
|  | 137 | } else { | 
|  | 138 | return -1; | 
|  | 139 | } | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | private: | 
|  | 143 | void CommonLayerSetup(); | 
|  | 144 |  | 
|  | 145 | Hwc2::Composer* hwc2_hidl_; | 
|  | 146 |  | 
|  | 147 | // Original display surface array index for tracking purposes. | 
|  | 148 | size_t surface_index_; | 
|  | 149 |  | 
|  | 150 | // The hardware composer layer and metrics to use during the prepare cycle. | 
|  | 151 | hwc2_layer_t hardware_composer_layer_; | 
|  | 152 | HWCDisplayMetrics* display_metrics_; | 
|  | 153 |  | 
|  | 154 | // Layer properties used to setup the hardware composer layer during the | 
|  | 155 | // Prepare phase. | 
|  | 156 | hwc2_blend_mode_t blending_; | 
|  | 157 | hwc_transform_t transform_; | 
|  | 158 | hwc2_composition_t composition_type_; | 
|  | 159 |  | 
|  | 160 | // These two members are mutually exclusive. When direct_buffer_ is set the | 
|  | 161 | // Layer gets its contents directly from that buffer; when surface_ is set the | 
|  | 162 | // Layer gets it contents from the surface's buffer train. | 
|  | 163 | std::shared_ptr<IonBuffer> direct_buffer_; | 
|  | 164 | std::shared_ptr<DisplaySurface> surface_; | 
|  | 165 |  | 
|  | 166 | // State when associated with a display surface. | 
|  | 167 | AcquiredBuffer acquired_buffer_; | 
|  | 168 | pdx::LocalHandle release_fence_; | 
|  | 169 |  | 
|  | 170 | pdx::LocalHandle acquire_fence_fd_; | 
|  | 171 | bool surface_rect_functions_applied_; | 
|  | 172 |  | 
|  | 173 | Layer(const Layer&) = delete; | 
|  | 174 | void operator=(const Layer&) = delete; | 
|  | 175 | }; | 
|  | 176 |  | 
|  | 177 | // HardwareComposer encapsulates the hardware composer HAL, exposing a | 
|  | 178 | // simplified API to post buffers to the display. | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 179 | // | 
|  | 180 | // HardwareComposer is accessed by both the vr flinger dispatcher thread and the | 
|  | 181 | // surface flinger main thread, in addition to internally running a separate | 
|  | 182 | // thread for compositing/EDS and posting layers to the HAL. When changing how | 
|  | 183 | // variables are used or adding new state think carefully about which threads | 
|  | 184 | // will access the state and whether it needs to be synchronized. | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 185 | class HardwareComposer { | 
|  | 186 | public: | 
|  | 187 | // Type for vsync callback. | 
|  | 188 | using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>; | 
|  | 189 |  | 
|  | 190 | // Since there is no universal way to query the number of hardware layers, | 
|  | 191 | // just set it to 4 for now. | 
|  | 192 | static constexpr int kMaxHardwareLayers = 4; | 
|  | 193 |  | 
|  | 194 | HardwareComposer(); | 
|  | 195 | HardwareComposer(Hwc2::Composer* hidl); | 
|  | 196 | ~HardwareComposer(); | 
|  | 197 |  | 
| Stephen Kiazyk | 016e5e3 | 2017-02-21 17:09:22 -0800 | [diff] [blame] | 198 | bool Initialize(); | 
|  | 199 |  | 
|  | 200 | bool IsInitialized() const { return initialized_; } | 
|  | 201 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 202 | // Start the post thread if there's work to do (i.e. visible layers). This | 
|  | 203 | // should only be called from surface flinger's main thread. | 
|  | 204 | void Enable(); | 
|  | 205 | // Pause the post thread, blocking until the post thread has signaled that | 
|  | 206 | // it's paused. This should only be called from surface flinger's main thread. | 
|  | 207 | void Disable(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 208 |  | 
|  | 209 | // Get the HMD display metrics for the current display. | 
|  | 210 | DisplayMetrics GetHmdDisplayMetrics() const; | 
|  | 211 |  | 
|  | 212 | int32_t GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config, | 
|  | 213 | hwc2_attribute_t attributes, | 
|  | 214 | int32_t* out_value) const; | 
|  | 215 | int32_t GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config, | 
|  | 216 | HWCDisplayMetrics* out_metrics) const; | 
|  | 217 | void Dump(char* buffer, uint32_t* out_size); | 
|  | 218 |  | 
|  | 219 | void SetVSyncCallback(VSyncCallback callback); | 
|  | 220 |  | 
|  | 221 | // Metrics of the logical display, which is always landscape. | 
|  | 222 | int DisplayWidth() const { return display_metrics_.width; } | 
|  | 223 | int DisplayHeight() const { return display_metrics_.height; } | 
|  | 224 | HWCDisplayMetrics display_metrics() const { return display_metrics_; } | 
|  | 225 |  | 
|  | 226 | // Metrics of the native display, which depends on the specific hardware | 
|  | 227 | // implementation of the display. | 
|  | 228 | HWCDisplayMetrics native_display_metrics() const { | 
|  | 229 | return native_display_metrics_; | 
|  | 230 | } | 
|  | 231 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 232 | // Set the display surface stack to compose to the display each frame. | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 233 | void SetDisplaySurfaces( | 
|  | 234 | std::vector<std::shared_ptr<DisplaySurface>> surfaces); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 235 |  | 
|  | 236 | Compositor* GetCompositor() { return &compositor_; } | 
|  | 237 |  | 
| Steven Thomas | 3cfac28 | 2017-02-06 12:29:30 -0800 | [diff] [blame] | 238 | void OnHardwareComposerRefresh(); | 
|  | 239 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 240 | private: | 
|  | 241 | int32_t EnableVsync(bool enabled); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 242 |  | 
|  | 243 | class ComposerCallback : public Hwc2::IComposerCallback { | 
|  | 244 | public: | 
|  | 245 | ComposerCallback() {} | 
|  | 246 |  | 
|  | 247 | hardware::Return<void> onHotplug(Hwc2::Display /*display*/, | 
|  | 248 | Connection /*connected*/) override { | 
|  | 249 | // TODO(skiazyk): depending on how the server is implemented, we might | 
|  | 250 | // have to set it up to synchronize with receiving this event, as it can | 
|  | 251 | // potentially be a critical event for setting up state within the | 
|  | 252 | // hwc2 module. That is, we (technically) should not call any other hwc | 
|  | 253 | // methods until this method has been called after registering the | 
|  | 254 | // callbacks. | 
|  | 255 | return hardware::Void(); | 
|  | 256 | } | 
|  | 257 |  | 
|  | 258 | hardware::Return<void> onRefresh(Hwc2::Display /*display*/) override { | 
|  | 259 | return hardware::Void(); | 
|  | 260 | } | 
|  | 261 |  | 
|  | 262 | hardware::Return<void> onVsync(Hwc2::Display /*display*/, | 
|  | 263 | int64_t /*timestamp*/) override { | 
|  | 264 | return hardware::Void(); | 
|  | 265 | } | 
|  | 266 | }; | 
|  | 267 |  | 
|  | 268 | int32_t Validate(hwc2_display_t display); | 
|  | 269 | int32_t Present(hwc2_display_t display); | 
|  | 270 |  | 
|  | 271 | void SetBacklightBrightness(int brightness); | 
|  | 272 |  | 
|  | 273 | void PostLayers(bool is_geometry_changed); | 
|  | 274 | void PostThread(); | 
|  | 275 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 276 | // Check to see if we have a value written to post_thread_interrupt_event_fd_, | 
|  | 277 | // indicating a control thread interrupted the post thread. This clears the | 
|  | 278 | // post_thread_interrupt_event_fd_ state in the process. Returns true if an | 
|  | 279 | // interrupt was requested. | 
|  | 280 | bool CheckPostThreadInterruptEventFd(); | 
|  | 281 | // Blocks until either event_fd becomes readable, or we're interrupted by a | 
|  | 282 | // control thread. Any errors are returned as negative errno values. If we're | 
|  | 283 | // interrupted, kPostThreadInterrupted will be returned. | 
| Steven Thomas | 66747c1 | 2017-03-22 18:45:31 -0700 | [diff] [blame] | 284 | int PostThreadPollInterruptible(int event_fd, int requested_events); | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 285 |  | 
|  | 286 | // BlockUntilVSync, WaitForVSync, and SleepUntil are all blocking calls made | 
|  | 287 | // on the post thread that can be interrupted by a control thread. If | 
|  | 288 | // interrupted, these calls return kPostThreadInterrupted. | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 289 | int ReadWaitPPState(); | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 290 | int BlockUntilVSync(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 291 | int ReadVSyncTimestamp(int64_t* timestamp); | 
|  | 292 | int WaitForVSync(int64_t* timestamp); | 
|  | 293 | int SleepUntil(int64_t wakeup_timestamp); | 
|  | 294 |  | 
|  | 295 | bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; } | 
|  | 296 |  | 
|  | 297 | // Returns true if the layer config changed, false otherwise | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 298 | bool UpdateLayerConfig(); | 
|  | 299 | void PostCompositorBuffers(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 300 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 301 | // Return true if the post thread has work to do (i.e. there are visible | 
|  | 302 | // surfaces to post to the screen). Must be called with post_thread_mutex_ | 
|  | 303 | // locked. Called only from the post thread. | 
|  | 304 | bool PostThreadHasWork(); | 
|  | 305 |  | 
|  | 306 | // Called on the post thread when the post thread is resumed. | 
|  | 307 | void OnPostThreadResumed(); | 
|  | 308 | // Called on the post thread when the post thread is paused or quits. | 
|  | 309 | void OnPostThreadPaused(); | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 310 |  | 
|  | 311 | struct FrameTimeMeasurementRecord { | 
|  | 312 | int64_t start_time; | 
|  | 313 | pdx::LocalHandle fence; | 
|  | 314 |  | 
|  | 315 | FrameTimeMeasurementRecord(FrameTimeMeasurementRecord&&) = default; | 
|  | 316 | FrameTimeMeasurementRecord& operator=(FrameTimeMeasurementRecord&&) = | 
|  | 317 | default; | 
|  | 318 | FrameTimeMeasurementRecord(const FrameTimeMeasurementRecord&) = delete; | 
|  | 319 | FrameTimeMeasurementRecord& operator=(const FrameTimeMeasurementRecord&) = | 
|  | 320 | delete; | 
|  | 321 | }; | 
|  | 322 |  | 
|  | 323 | void UpdateFrameTimeHistory(std::vector<FrameTimeMeasurementRecord>* backlog, | 
|  | 324 | int backlog_max, | 
|  | 325 | FenceInfoBuffer* fence_info_buffer, | 
|  | 326 | FrameTimeHistory* history); | 
|  | 327 |  | 
|  | 328 | // Returns true if the frame finished rendering, false otherwise. If the frame | 
|  | 329 | // finished the frame end time is stored in timestamp. Doesn't block. | 
|  | 330 | bool CheckFrameFinished(int frame_fence_fd, | 
|  | 331 | FenceInfoBuffer* fence_info_buffer, | 
|  | 332 | int64_t* timestamp); | 
|  | 333 |  | 
|  | 334 | void HandlePendingScreenshots(); | 
|  | 335 |  | 
| Stephen Kiazyk | 016e5e3 | 2017-02-21 17:09:22 -0800 | [diff] [blame] | 336 | bool initialized_; | 
|  | 337 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 338 | // Hardware composer HAL device. | 
|  | 339 | std::unique_ptr<Hwc2::Composer> hwc2_hidl_; | 
|  | 340 | sp<ComposerCallback> callbacks_; | 
|  | 341 |  | 
|  | 342 | // Display metrics of the physical display. | 
|  | 343 | HWCDisplayMetrics native_display_metrics_; | 
|  | 344 | // Display metrics of the logical display, adjusted so that orientation is | 
|  | 345 | // landscape. | 
|  | 346 | HWCDisplayMetrics display_metrics_; | 
|  | 347 | // Transform required to get from native to logical display orientation. | 
|  | 348 | hwc_transform_t display_transform_; | 
|  | 349 |  | 
|  | 350 | // Buffer for the background layer required by hardware composer. | 
|  | 351 | std::shared_ptr<IonBuffer> framebuffer_target_; | 
|  | 352 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 353 | // Protects access to variables used by the post thread and one of the control | 
|  | 354 | // threads (either the vr flinger dispatcher thread or the surface flinger | 
|  | 355 | // main thread). This includes active_surfaces_, active_surfaces_updated_, | 
|  | 356 | // post_thread_enabled_, post_thread_running_, and | 
|  | 357 | // post_thread_quit_requested_. | 
|  | 358 | std::mutex post_thread_mutex_; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 359 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 360 | // Surfaces configured by the display manager. Written by the vr flinger | 
|  | 361 | // dispatcher thread, read by the post thread. | 
|  | 362 | std::vector<std::shared_ptr<DisplaySurface>> active_surfaces_; | 
|  | 363 | // active_surfaces_updated_ is set to true by the vr flinger dispatcher thread | 
|  | 364 | // when the list of active surfaces changes. active_surfaces_updated_ will be | 
|  | 365 | // set back to false by the post thread when it processes the update. | 
|  | 366 | bool active_surfaces_updated_; | 
|  | 367 |  | 
|  | 368 | // The surfaces displayed by the post thread. Used exclusively by the post | 
|  | 369 | // thread. | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 370 | std::vector<std::shared_ptr<DisplaySurface>> display_surfaces_; | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 371 |  | 
|  | 372 | // The surfaces rendered by the compositor. Used exclusively by the post | 
|  | 373 | // thread. | 
|  | 374 | std::vector<std::shared_ptr<DisplaySurface>> compositor_surfaces_; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 375 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 376 | // Layer array for handling buffer flow into hardware composer layers. | 
|  | 377 | // Note that the first array is the actual storage for the layer objects, | 
|  | 378 | // and the latter is an array of pointers, which can be freely re-arranged | 
|  | 379 | // without messing up the underlying objects. | 
|  | 380 | std::array<Layer, kMaxHardwareLayers> layer_storage_; | 
|  | 381 | std::array<Layer*, kMaxHardwareLayers> layers_; | 
|  | 382 | size_t active_layer_count_; | 
|  | 383 |  | 
|  | 384 | // Set by the Post thread to the index of the GPU compositing output | 
|  | 385 | // buffer in the layers_ array. | 
|  | 386 | Layer* gpu_layer_; | 
|  | 387 |  | 
|  | 388 | // Handler to hook vsync events outside of this class. | 
|  | 389 | VSyncCallback vsync_callback_; | 
|  | 390 |  | 
| Steven Thomas | 282a5ed | 2017-02-07 18:07:01 -0800 | [diff] [blame] | 391 | // The layer posting thread. This thread wakes up a short time before vsync to | 
|  | 392 | // hand buffers to post processing and the results to hardware composer. | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 393 | std::thread post_thread_; | 
|  | 394 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 395 | // Set to true if the post thread is allowed to run. Surface flinger and vr | 
|  | 396 | // flinger share access to the display, and vr flinger shouldn't use the | 
|  | 397 | // display while surface flinger is using it. While surface flinger owns the | 
|  | 398 | // display, post_thread_enabled_ will be set to false to indicate the post | 
|  | 399 | // thread shouldn't run. | 
|  | 400 | bool post_thread_enabled_; | 
|  | 401 | // Set to true by the post thread if it's currently running. | 
|  | 402 | bool post_thread_running_; | 
|  | 403 | // Set to true if the post thread should quit. Only set when destroying the | 
|  | 404 | // HardwareComposer instance. | 
|  | 405 | bool post_thread_quit_requested_; | 
|  | 406 | // Used to wake the post thread up while it's waiting for vsync or sleeping | 
|  | 407 | // until EDS preemption, for faster transition to the paused state. | 
|  | 408 | pdx::LocalHandle post_thread_interrupt_event_fd_; | 
| Steven Thomas | 282a5ed | 2017-02-07 18:07:01 -0800 | [diff] [blame] | 409 | // Used to communicate between the control thread and the post thread. | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 410 | std::condition_variable post_thread_cond_var_; | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 411 |  | 
|  | 412 | // Backlight LED brightness sysfs node. | 
|  | 413 | pdx::LocalHandle backlight_brightness_fd_; | 
|  | 414 |  | 
|  | 415 | // Primary display vsync event sysfs node. | 
|  | 416 | pdx::LocalHandle primary_display_vsync_event_fd_; | 
|  | 417 |  | 
|  | 418 | // Primary display wait_pingpong state sysfs node. | 
|  | 419 | pdx::LocalHandle primary_display_wait_pp_fd_; | 
|  | 420 |  | 
|  | 421 | // VSync sleep timerfd. | 
|  | 422 | pdx::LocalHandle vsync_sleep_timer_fd_; | 
|  | 423 |  | 
|  | 424 | // The timestamp of the last vsync. | 
|  | 425 | int64_t last_vsync_timestamp_; | 
|  | 426 |  | 
|  | 427 | // Vsync count since display on. | 
|  | 428 | uint32_t vsync_count_; | 
|  | 429 |  | 
|  | 430 | // Counter tracking the number of skipped frames. | 
|  | 431 | int frame_skip_count_; | 
|  | 432 |  | 
|  | 433 | // After construction, only accessed on post_thread_. | 
|  | 434 | Compositor compositor_; | 
|  | 435 |  | 
|  | 436 | // Fd array for tracking retire fences that are returned by hwc. This allows | 
|  | 437 | // us to detect when the display driver begins queuing frames. | 
|  | 438 | std::vector<pdx::LocalHandle> retire_fence_fds_; | 
|  | 439 |  | 
|  | 440 | // Pose client for frame count notifications. Pose client predicts poses | 
|  | 441 | // out to display frame boundaries, so we need to tell it about vsyncs. | 
|  | 442 | DvrPose* pose_client_; | 
|  | 443 |  | 
| Steven Thomas | 050b2c8 | 2017-03-06 11:45:16 -0800 | [diff] [blame] | 444 | // Our history of frame times. This is used to get a better estimate of how | 
|  | 445 | // long the next frame will take, to set a schedule for EDS. | 
|  | 446 | FrameTimeHistory frame_time_history_; | 
|  | 447 |  | 
|  | 448 | // The backlog is used to allow us to start rendering the next frame before | 
|  | 449 | // the previous frame has finished, and still get an accurate measurement of | 
|  | 450 | // frame duration. | 
|  | 451 | std::vector<FrameTimeMeasurementRecord> frame_time_backlog_; | 
|  | 452 |  | 
|  | 453 | static constexpr int kPostThreadInterrupted = 1; | 
|  | 454 |  | 
| Alex Vakulenko | a8a9278 | 2017-01-27 14:41:57 -0800 | [diff] [blame] | 455 | static void HwcRefresh(hwc2_callback_data_t data, hwc2_display_t display); | 
|  | 456 | static void HwcVSync(hwc2_callback_data_t data, hwc2_display_t display, | 
|  | 457 | int64_t timestamp); | 
|  | 458 | static void HwcHotplug(hwc2_callback_data_t callbackData, | 
|  | 459 | hwc2_display_t display, hwc2_connection_t connected); | 
|  | 460 |  | 
|  | 461 | HardwareComposer(const HardwareComposer&) = delete; | 
|  | 462 | void operator=(const HardwareComposer&) = delete; | 
|  | 463 | }; | 
|  | 464 |  | 
|  | 465 | }  // namespace dvr | 
|  | 466 | }  // namespace android | 
|  | 467 |  | 
|  | 468 | #endif  // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_ |