• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
2 #define ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
3 
4 #include <ui/GraphicBuffer.h>
5 #include "DisplayHardware/ComposerHal.h"
6 #include "hwc_types.h"
7 
8 #include <dvr/dvr_shared_buffers.h>
9 #include <hardware/gralloc.h>
10 #include <log/log.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 <dvr/dvr_config.h>
21 #include <dvr/dvr_vsync.h>
22 #include <pdx/file_handle.h>
23 #include <pdx/rpc/variant.h>
24 #include <private/dvr/buffer_hub_client.h>
25 #include <private/dvr/shared_buffer_helpers.h>
26 
27 #include "acquired_buffer.h"
28 #include "display_surface.h"
29 
30 // Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
31 #ifndef HWC_TRANSFORM_NONE
32 #define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
33 #endif
34 
35 namespace android {
36 namespace dvr {
37 
38 // Basic display metrics for physical displays. Dimensions and densities are
39 // relative to the physical display orientation, which may be different from the
40 // logical display orientation exposed to applications.
41 struct HWCDisplayMetrics {
42   int width;
43   int height;
44   struct {
45     int x;
46     int y;
47   } dpi;
48   int vsync_period_ns;
49 };
50 
51 // Layer represents the connection between a hardware composer layer and the
52 // source supplying buffers for the layer's contents.
53 class Layer {
54  public:
55   Layer() = default;
56 
57   // Sets up the layer to use a display surface as its content source. The Layer
58   // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
59   // every frame.
60   //
61   // |blending| receives HWC_BLENDING_* values.
62   // |transform| receives HWC_TRANSFORM_* values.
63   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
64   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
65   // |index| is the index of this surface in the DirectDisplaySurface array.
66   Layer(const std::shared_ptr<DirectDisplaySurface>& surface,
67         HWC::BlendMode blending, HWC::Transform transform,
68         HWC::Composition composition_type, size_t z_roder);
69 
70   // Sets up the layer to use a direct buffer as its content source. No special
71   // handling of the buffer is performed; responsibility for updating or
72   // changing the buffer each frame is on the caller.
73   //
74   // |blending| receives HWC_BLENDING_* values.
75   // |transform| receives HWC_TRANSFORM_* values.
76   // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
77   // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
78   Layer(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
79         HWC::Transform transform, HWC::Composition composition_type,
80         size_t z_order);
81 
82   Layer(Layer&&);
83   Layer& operator=(Layer&&);
84 
85   ~Layer();
86 
87   // Releases any shared pointers and fence handles held by this instance.
88   void Reset();
89 
90   // Layers that use a direct IonBuffer should call this each frame to update
91   // which buffer will be used for the next PostLayers.
92   void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
93 
94   // Sets up the hardware composer layer for the next frame. When the layer is
95   // associated with a display surface, this method automatically ACQUIRES a new
96   // buffer if one is available.
97   void Prepare();
98 
99   // After calling prepare, if this frame is to be dropped instead of passing
100   // along to the HWC, call Drop to close the contained fence(s).
101   void Drop();
102 
103   // Performs fence bookkeeping after the frame has been posted to hardware
104   // composer.
105   void Finish(int release_fence_fd);
106 
107   // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
108   void SetBlending(HWC::BlendMode blending);
109 
110   // Sets the z-order of this layer
111   void SetZOrder(size_t z_order);
112 
113   // Gets the current IonBuffer associated with this layer. Ownership of the
114   // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
115   // remain valid across calls to Layer::Setup(), Layer::Prepare(), or
116   // Layer::Reset(). YOU HAVE BEEN WARNED.
117   IonBuffer* GetBuffer();
118 
GetCompositionType()119   HWC::Composition GetCompositionType() const { return composition_type_; }
GetLayerHandle()120   HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
IsLayerSetup()121   bool IsLayerSetup() const { return !source_.empty(); }
122 
GetSurfaceId()123   int GetSurfaceId() const {
124     int surface_id = -1;
125     pdx::rpc::IfAnyOf<SourceSurface>::Call(
126         &source_, [&surface_id](const SourceSurface& surface_source) {
127           surface_id = surface_source.GetSurfaceId();
128         });
129     return surface_id;
130   }
131 
GetBufferId()132   int GetBufferId() const {
133     int buffer_id = -1;
134     pdx::rpc::IfAnyOf<SourceSurface>::Call(
135         &source_, [&buffer_id](const SourceSurface& surface_source) {
136           buffer_id = surface_source.GetBufferId();
137         });
138     return buffer_id;
139   }
140 
141   // Compares Layers by surface id.
142   bool operator<(const Layer& other) const {
143     return GetSurfaceId() < other.GetSurfaceId();
144   }
145   bool operator<(int surface_id) const { return GetSurfaceId() < surface_id; }
146 
147   // Sets the composer instance used by all Layer instances.
SetComposer(Hwc2::Composer * composer)148   static void SetComposer(Hwc2::Composer* composer) { composer_ = composer; }
149 
150   // Sets the display metrics used by all Layer instances.
SetDisplayMetrics(HWCDisplayMetrics display_metrics)151   static void SetDisplayMetrics(HWCDisplayMetrics display_metrics) {
152     display_metrics_ = display_metrics;
153   }
154 
155  private:
156   void CommonLayerSetup();
157 
158   // Applies all of the settings to this layer using the hwc functions
159   void UpdateLayerSettings();
160 
161   // Applies visibility settings that may have changed.
162   void UpdateVisibilitySettings();
163 
164   // Checks whether the buffer, given by id, is associated with the given slot
165   // in the HWC buffer cache. If the slot is not associated with the given
166   // buffer the cache is updated to establish the association and the buffer
167   // should be sent to HWC using setLayerBuffer. Returns true if the association
168   // was already established, false if not. A buffer_id of -1 is never
169   // associated and always returns false.
170   bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id);
171 
172   // Composer instance shared by all instances of Layer. This must be set
173   // whenever a new instance of the Composer is created. This may be set to
174   // nullptr as long as there are no instances of Layer that might need to use
175   // it.
176   static Hwc2::Composer* composer_;
177 
178   // Display metrics shared by all instances of Layer. This must be set at least
179   // once during VrFlinger initialization and is expected to remain constant
180   // thereafter.
181   static HWCDisplayMetrics display_metrics_;
182 
183   // The hardware composer layer and metrics to use during the prepare cycle.
184   hwc2_layer_t hardware_composer_layer_ = 0;
185 
186   // Layer properties used to setup the hardware composer layer during the
187   // Prepare phase.
188   size_t z_order_ = 0;
189   HWC::BlendMode blending_ = HWC::BlendMode::None;
190   HWC::Transform transform_ = HWC::Transform::None;
191   HWC::Composition composition_type_ = HWC::Composition::Invalid;
192   HWC::Composition target_composition_type_ = HWC::Composition::Device;
193 
194   // State when the layer is connected to a surface. Provides the same interface
195   // as SourceBuffer to simplify internal use by Layer.
196   struct SourceSurface {
197     std::shared_ptr<DirectDisplaySurface> surface;
198     AcquiredBuffer acquired_buffer;
199     pdx::LocalHandle release_fence;
200 
SourceSurfaceSourceSurface201     SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
202         : surface(surface) {}
203 
204     // Attempts to acquire a new buffer from the surface and return a tuple with
205     // width, height, buffer handle, and fence. If a new buffer is not available
206     // the previous buffer is returned or an empty value if no buffer has ever
207     // been posted. When a new buffer is acquired the previous buffer's release
208     // fence is passed out automatically.
209     std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
AcquireSourceSurface210     Acquire() {
211       if (surface->IsBufferAvailable()) {
212         acquired_buffer.Release(std::move(release_fence));
213         acquired_buffer = surface->AcquireCurrentBuffer();
214         ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
215       }
216       if (!acquired_buffer.IsEmpty()) {
217         return std::make_tuple(
218             acquired_buffer.buffer()->width(),
219             acquired_buffer.buffer()->height(), acquired_buffer.buffer()->id(),
220             acquired_buffer.buffer()->buffer()->buffer(),
221             acquired_buffer.ClaimAcquireFence(), acquired_buffer.slot());
222       } else {
223         return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
224       }
225     }
226 
FinishSourceSurface227     void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
228 
229     // Gets a pointer to the current acquired buffer or returns nullptr if there
230     // isn't one.
GetBufferSourceSurface231     IonBuffer* GetBuffer() {
232       if (acquired_buffer.IsAvailable())
233         return acquired_buffer.buffer()->buffer();
234       else
235         return nullptr;
236     }
237 
238     // Returns the surface id of the surface.
GetSurfaceIdSourceSurface239     int GetSurfaceId() const { return surface->surface_id(); }
240 
241     // Returns the buffer id for the current buffer.
GetBufferIdSourceSurface242     int GetBufferId() const {
243       if (acquired_buffer.IsAvailable())
244         return acquired_buffer.buffer()->id();
245       else
246         return -1;
247     }
248   };
249 
250   // State when the layer is connected to a buffer. Provides the same interface
251   // as SourceSurface to simplify internal use by Layer.
252   struct SourceBuffer {
253     std::shared_ptr<IonBuffer> buffer;
254 
255     std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
AcquireSourceBuffer256     Acquire() {
257       if (buffer)
258         return std::make_tuple(buffer->width(), buffer->height(), -1,
259                                buffer->buffer(), pdx::LocalHandle{}, 0);
260       else
261         return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
262     }
263 
FinishSourceBuffer264     void Finish(pdx::LocalHandle /*fence*/) {}
265 
GetBufferSourceBuffer266     IonBuffer* GetBuffer() { return buffer.get(); }
267 
GetSurfaceIdSourceBuffer268     int GetSurfaceId() const { return -1; }
GetBufferIdSourceBuffer269     int GetBufferId() const { return -1; }
270   };
271 
272   // The underlying hardware composer layer is supplied buffers either from a
273   // surface buffer train or from a buffer directly.
274   pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
275 
276   pdx::LocalHandle acquire_fence_;
277   bool surface_rect_functions_applied_ = false;
278   bool pending_visibility_settings_ = true;
279 
280   // Map of buffer slot assignments that have already been established with HWC:
281   // slot -> buffer_id. When this map contains a matching slot and buffer_id the
282   // buffer argument to setLayerBuffer may be nullptr to avoid the cost of
283   // importing a buffer HWC already knows about.
284   std::map<std::size_t, int> cached_buffer_map_;
285 
286   Layer(const Layer&) = delete;
287   void operator=(const Layer&) = delete;
288 };
289 
290 // HardwareComposer encapsulates the hardware composer HAL, exposing a
291 // simplified API to post buffers to the display.
292 //
293 // HardwareComposer is accessed by both the vr flinger dispatcher thread and the
294 // surface flinger main thread, in addition to internally running a separate
295 // thread for compositing/EDS and posting layers to the HAL. When changing how
296 // variables are used or adding new state think carefully about which threads
297 // will access the state and whether it needs to be synchronized.
298 class HardwareComposer {
299  public:
300   // Type for vsync callback.
301   using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
302   using RequestDisplayCallback = std::function<void(bool)>;
303 
304   HardwareComposer();
305   ~HardwareComposer();
306 
307   bool Initialize(Hwc2::Composer* composer,
308                   RequestDisplayCallback request_display_callback);
309 
IsInitialized()310   bool IsInitialized() const { return initialized_; }
311 
312   // Start the post thread if there's work to do (i.e. visible layers). This
313   // should only be called from surface flinger's main thread.
314   void Enable();
315   // Pause the post thread, blocking until the post thread has signaled that
316   // it's paused. This should only be called from surface flinger's main thread.
317   void Disable();
318 
319   // Get the HMD display metrics for the current display.
320   display::Metrics GetHmdDisplayMetrics() const;
321 
322   std::string Dump();
323 
324   void SetVSyncCallback(VSyncCallback callback);
325 
326   // Metrics of the logical display, which is always landscape.
DisplayWidth()327   int DisplayWidth() const { return display_metrics_.width; }
DisplayHeight()328   int DisplayHeight() const { return display_metrics_.height; }
display_metrics()329   HWCDisplayMetrics display_metrics() const { return display_metrics_; }
330 
331   // Metrics of the native display, which depends on the specific hardware
332   // implementation of the display.
native_display_metrics()333   HWCDisplayMetrics native_display_metrics() const {
334     return native_display_metrics_;
335   }
336 
337   // Sets the display surfaces to compose the hardware layer stack.
338   void SetDisplaySurfaces(
339       std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
340 
341   int OnNewGlobalBuffer(DvrGlobalBufferKey key, IonBuffer& ion_buffer);
342   void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);
343 
344  private:
345   HWC::Error GetDisplayAttribute(Hwc2::Composer* composer,
346                                  hwc2_display_t display, hwc2_config_t config,
347                                  hwc2_attribute_t attributes,
348                                  int32_t* out_value) const;
349   HWC::Error GetDisplayMetrics(Hwc2::Composer* composer, hwc2_display_t display,
350                                hwc2_config_t config,
351                                HWCDisplayMetrics* out_metrics) const;
352 
353   HWC::Error EnableVsync(bool enabled);
354   HWC::Error SetPowerMode(bool active);
355 
356   class ComposerCallback : public Hwc2::IComposerCallback {
357    public:
358     ComposerCallback() = default;
359     hardware::Return<void> onHotplug(Hwc2::Display display,
360                                      Connection conn) override;
361     hardware::Return<void> onRefresh(Hwc2::Display display) override;
362     hardware::Return<void> onVsync(Hwc2::Display display,
363                                    int64_t timestamp) override;
364 
365     pdx::Status<int64_t> GetVsyncTime(Hwc2::Display display);
366 
367    private:
368     std::mutex vsync_mutex_;
369 
370     struct Display {
371       pdx::LocalHandle driver_vsync_event_fd;
372       int64_t callback_vsync_timestamp{0};
373     };
374     std::array<Display, HWC_NUM_PHYSICAL_DISPLAY_TYPES> displays_;
375   };
376 
377   HWC::Error Validate(hwc2_display_t display);
378   HWC::Error Present(hwc2_display_t display);
379 
380   void SetBacklightBrightness(int brightness);
381 
382   void PostLayers();
383   void PostThread();
384 
385   // The post thread has two controlling states:
386   // 1. Idle: no work to do (no visible surfaces).
387   // 2. Suspended: explicitly halted (system is not in VR mode).
388   // When either #1 or #2 is true then the post thread is quiescent, otherwise
389   // it is active.
390   using PostThreadStateType = uint32_t;
391   struct PostThreadState {
392     enum : PostThreadStateType {
393       Active = 0,
394       Idle = (1 << 0),
395       Suspended = (1 << 1),
396       Quit = (1 << 2),
397     };
398   };
399 
400   void UpdatePostThreadState(uint32_t state, bool suspend);
401 
402   // Blocks until either event_fd becomes readable, or we're interrupted by a
403   // control thread, or timeout_ms is reached before any events occur. Any
404   // errors are returned as negative errno values, with -ETIMEDOUT returned in
405   // the case of a timeout. If we're interrupted, kPostThreadInterrupted will be
406   // returned.
407   int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
408                                   int requested_events, int timeout_ms);
409 
410   // WaitForVSync and SleepUntil are blocking calls made on the post thread that
411   // can be interrupted by a control thread. If interrupted, these calls return
412   // kPostThreadInterrupted.
413   int ReadWaitPPState();
414   pdx::Status<int64_t> WaitForVSync();
415   pdx::Status<int64_t> GetVSyncTime();
416   int SleepUntil(int64_t wakeup_timestamp);
417 
418   // Reconfigures the layer stack if the display surfaces changed since the last
419   // frame. Called only from the post thread.
420   bool UpdateLayerConfig();
421 
422   // Called on the post thread when the post thread is resumed.
423   void OnPostThreadResumed();
424   // Called on the post thread when the post thread is paused or quits.
425   void OnPostThreadPaused();
426 
427   // Map the given shared memory buffer to our broadcast ring to track updates
428   // to the config parameters.
429   int MapConfigBuffer(IonBuffer& ion_buffer);
430   void ConfigBufferDeleted();
431   // Poll for config udpates.
432   void UpdateConfigBuffer();
433 
434   bool initialized_;
435   bool is_standalone_device_;
436 
437   std::unique_ptr<Hwc2::Composer> composer_;
438   sp<ComposerCallback> composer_callback_;
439   RequestDisplayCallback request_display_callback_;
440 
441   // Display metrics of the physical display.
442   HWCDisplayMetrics native_display_metrics_;
443   // Display metrics of the logical display, adjusted so that orientation is
444   // landscape.
445   HWCDisplayMetrics display_metrics_;
446   // Transform required to get from native to logical display orientation.
447   HWC::Transform display_transform_ = HWC::Transform::None;
448 
449   // Pending surface list. Set by the display service when DirectSurfaces are
450   // added, removed, or change visibility. Written by the message dispatch
451   // thread and read by the post thread.
452   std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
453 
454   // Layer set for handling buffer flow into hardware composer layers. This
455   // vector must be sorted by surface_id in ascending order.
456   std::vector<Layer> layers_;
457 
458   // Handler to hook vsync events outside of this class.
459   VSyncCallback vsync_callback_;
460 
461   // The layer posting thread. This thread wakes up a short time before vsync to
462   // hand buffers to hardware composer.
463   std::thread post_thread_;
464 
465   // Post thread state machine and synchronization primitives.
466   PostThreadStateType post_thread_state_{PostThreadState::Idle |
467                                          PostThreadState::Suspended};
468   std::atomic<bool> post_thread_quiescent_{true};
469   bool post_thread_resumed_{false};
470   pdx::LocalHandle post_thread_event_fd_;
471   std::mutex post_thread_mutex_;
472   std::condition_variable post_thread_wait_;
473   std::condition_variable post_thread_ready_;
474 
475   // Backlight LED brightness sysfs node.
476   pdx::LocalHandle backlight_brightness_fd_;
477 
478   // VSync sleep timerfd.
479   pdx::LocalHandle vsync_sleep_timer_fd_;
480 
481   // The timestamp of the last vsync.
482   int64_t last_vsync_timestamp_ = 0;
483 
484   // The number of vsync intervals to predict since the last vsync.
485   int vsync_prediction_interval_ = 1;
486 
487   // Vsync count since display on.
488   uint32_t vsync_count_ = 0;
489 
490   // Counter tracking the number of skipped frames.
491   int frame_skip_count_ = 0;
492 
493   // Fd array for tracking retire fences that are returned by hwc. This allows
494   // us to detect when the display driver begins queuing frames.
495   std::vector<pdx::LocalHandle> retire_fence_fds_;
496 
497   // If we are publishing vsync data, we will put it here.
498   std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
499 
500   // Broadcast ring for receiving config data from the DisplayManager.
501   DvrConfigRing shared_config_ring_;
502   uint32_t shared_config_ring_sequence_{0};
503   // Config buffer for reading from the post thread.
504   DvrConfig post_thread_config_;
505   std::mutex shared_config_mutex_;
506 
507   static constexpr int kPostThreadInterrupted = 1;
508 
509   HardwareComposer(const HardwareComposer&) = delete;
510   void operator=(const HardwareComposer&) = delete;
511 };
512 
513 }  // namespace dvr
514 }  // namespace android
515 
516 #endif  // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
517