blob: bfce10b5b060327db78f8d23be019555569fd9dd [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#ifndef ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
2#define ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_
3
Corey Tabaka2251d822017-04-20 16:04:07 -07004#include <ui/GraphicBuffer.h>
5#include "DisplayHardware/ComposerHal.h"
6#include "hwc_types.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08007
Okan Arikan822b7102017-05-08 13:31:34 -07008#include <dvr/dvr_shared_buffers.h>
Corey Tabaka2251d822017-04-20 16:04:07 -07009#include <hardware/gralloc.h>
10#include <log/log.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080011
12#include <array>
13#include <condition_variable>
14#include <memory>
15#include <mutex>
Steven Thomasbfe46a02018-02-16 14:27:35 -080016#include <optional>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080017#include <thread>
18#include <tuple>
19#include <vector>
20
Okan Arikan6f468c62017-05-31 14:48:30 -070021#include <dvr/dvr_config.h>
Okan Arikan822b7102017-05-08 13:31:34 -070022#include <dvr/dvr_vsync.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080023#include <pdx/file_handle.h>
Corey Tabaka2251d822017-04-20 16:04:07 -070024#include <pdx/rpc/variant.h>
Okan Arikan822b7102017-05-08 13:31:34 -070025#include <private/dvr/shared_buffer_helpers.h>
Steven Thomasdfde8fa2018-04-19 16:00:58 -070026#include <private/dvr/vsync_service.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080027
mamik913cc132019-09-13 14:58:43 -070028#include "DisplayHardware/DisplayIdentification.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080029#include "acquired_buffer.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080030#include "display_surface.h"
31
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080032// Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
33#ifndef HWC_TRANSFORM_NONE
34#define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
35#endif
36
37namespace android {
38namespace dvr {
39
Steven Thomasbfe46a02018-02-16 14:27:35 -080040// Basic display metrics for physical displays.
41struct DisplayParams {
42 hwc2_display_t id;
43 bool is_primary;
44
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080045 int width;
46 int height;
Steven Thomasbfe46a02018-02-16 14:27:35 -080047
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080048 struct {
49 int x;
50 int y;
51 } dpi;
Steven Thomasbfe46a02018-02-16 14:27:35 -080052
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080053 int vsync_period_ns;
54};
55
56// Layer represents the connection between a hardware composer layer and the
57// source supplying buffers for the layer's contents.
58class Layer {
59 public:
Corey Tabaka2c4aea32017-08-31 20:01:15 -070060 Layer() = default;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080061
62 // Sets up the layer to use a display surface as its content source. The Layer
Corey Tabaka2251d822017-04-20 16:04:07 -070063 // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
64 // every frame.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080065 //
Steven Thomasbfe46a02018-02-16 14:27:35 -080066 // |composer| The composer instance.
67 // |display_params| Info about the display to use.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080068 // |blending| receives HWC_BLENDING_* values.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080069 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
70 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Corey Tabaka2251d822017-04-20 16:04:07 -070071 // |index| is the index of this surface in the DirectDisplaySurface array.
Steven Thomasbfe46a02018-02-16 14:27:35 -080072 Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
73 const std::shared_ptr<DirectDisplaySurface>& surface,
74 HWC::BlendMode blending, HWC::Composition composition_type,
75 size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080076
77 // Sets up the layer to use a direct buffer as its content source. No special
78 // handling of the buffer is performed; responsibility for updating or
79 // changing the buffer each frame is on the caller.
80 //
Steven Thomasbfe46a02018-02-16 14:27:35 -080081 // |composer| The composer instance.
82 // |display_params| Info about the display to use.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080083 // |blending| receives HWC_BLENDING_* values.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080084 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
85 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Steven Thomasbfe46a02018-02-16 14:27:35 -080086 Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
87 const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
88 HWC::Composition composition_type, size_t z_order);
Corey Tabaka2c4aea32017-08-31 20:01:15 -070089
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070090 Layer(Layer&&) noexcept;
91 Layer& operator=(Layer&&) noexcept;
Corey Tabaka2c4aea32017-08-31 20:01:15 -070092
93 ~Layer();
94
95 // Releases any shared pointers and fence handles held by this instance.
96 void Reset();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080097
98 // Layers that use a direct IonBuffer should call this each frame to update
99 // which buffer will be used for the next PostLayers.
Corey Tabaka2251d822017-04-20 16:04:07 -0700100 void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800101
102 // Sets up the hardware composer layer for the next frame. When the layer is
103 // associated with a display surface, this method automatically ACQUIRES a new
104 // buffer if one is available.
105 void Prepare();
106
107 // After calling prepare, if this frame is to be dropped instead of passing
108 // along to the HWC, call Drop to close the contained fence(s).
109 void Drop();
110
111 // Performs fence bookkeeping after the frame has been posted to hardware
112 // composer.
113 void Finish(int release_fence_fd);
114
115 // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
Corey Tabaka2251d822017-04-20 16:04:07 -0700116 void SetBlending(HWC::BlendMode blending);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800117
Corey Tabaka2251d822017-04-20 16:04:07 -0700118 // Sets the z-order of this layer
119 void SetZOrder(size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800120
121 // Gets the current IonBuffer associated with this layer. Ownership of the
122 // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
123 // remain valid across calls to Layer::Setup(), Layer::Prepare(), or
124 // Layer::Reset(). YOU HAVE BEEN WARNED.
125 IonBuffer* GetBuffer();
126
Corey Tabaka2251d822017-04-20 16:04:07 -0700127 HWC::Composition GetCompositionType() const { return composition_type_; }
128 HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
129 bool IsLayerSetup() const { return !source_.empty(); }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800130
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800131 int GetSurfaceId() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700132 int surface_id = -1;
133 pdx::rpc::IfAnyOf<SourceSurface>::Call(
134 &source_, [&surface_id](const SourceSurface& surface_source) {
Corey Tabaka0b485c92017-05-19 12:02:58 -0700135 surface_id = surface_source.GetSurfaceId();
Corey Tabaka2251d822017-04-20 16:04:07 -0700136 });
137 return surface_id;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800138 }
139
Corey Tabaka0b485c92017-05-19 12:02:58 -0700140 int GetBufferId() const {
141 int buffer_id = -1;
142 pdx::rpc::IfAnyOf<SourceSurface>::Call(
143 &source_, [&buffer_id](const SourceSurface& surface_source) {
144 buffer_id = surface_source.GetBufferId();
145 });
146 return buffer_id;
147 }
148
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700149 // Compares Layers by surface id.
150 bool operator<(const Layer& other) const {
151 return GetSurfaceId() < other.GetSurfaceId();
152 }
Corey Tabakab3732f02017-09-16 00:58:54 -0700153 bool operator<(int surface_id) const { return GetSurfaceId() < surface_id; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800154
Steven Thomasbfe46a02018-02-16 14:27:35 -0800155 void IgnoreBadDisplayErrorsOnDestroy(bool ignore) {
156 ignore_bad_display_errors_on_destroy_ = ignore;
Steven Thomas6e8f7062017-11-22 14:15:29 -0800157 }
158
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700159 private:
160 void CommonLayerSetup();
161
162 // Applies all of the settings to this layer using the hwc functions
163 void UpdateLayerSettings();
164
165 // Applies visibility settings that may have changed.
166 void UpdateVisibilitySettings();
167
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700168 // Checks whether the buffer, given by id, is associated with the given slot
169 // in the HWC buffer cache. If the slot is not associated with the given
170 // buffer the cache is updated to establish the association and the buffer
171 // should be sent to HWC using setLayerBuffer. Returns true if the association
172 // was already established, false if not. A buffer_id of -1 is never
173 // associated and always returns false.
174 bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id);
175
Steven Thomasbfe46a02018-02-16 14:27:35 -0800176 // Composer instance.
177 Hwc2::Composer* composer_ = nullptr;
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700178
Steven Thomasbfe46a02018-02-16 14:27:35 -0800179 // Parameters of the display to use for this layer.
180 DisplayParams display_params_;
Steven Thomas6e8f7062017-11-22 14:15:29 -0800181
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800182 // The hardware composer layer and metrics to use during the prepare cycle.
Corey Tabaka2251d822017-04-20 16:04:07 -0700183 hwc2_layer_t hardware_composer_layer_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800184
185 // Layer properties used to setup the hardware composer layer during the
186 // Prepare phase.
Corey Tabaka2251d822017-04-20 16:04:07 -0700187 size_t z_order_ = 0;
188 HWC::BlendMode blending_ = HWC::BlendMode::None;
Corey Tabaka2251d822017-04-20 16:04:07 -0700189 HWC::Composition composition_type_ = HWC::Composition::Invalid;
190 HWC::Composition target_composition_type_ = HWC::Composition::Device;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800191
Corey Tabaka2251d822017-04-20 16:04:07 -0700192 // State when the layer is connected to a surface. Provides the same interface
193 // as SourceBuffer to simplify internal use by Layer.
194 struct SourceSurface {
195 std::shared_ptr<DirectDisplaySurface> surface;
196 AcquiredBuffer acquired_buffer;
197 pdx::LocalHandle release_fence;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800198
Chih-Hung Hsieh79e7f1b2018-12-20 15:53:43 -0800199 explicit SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
Corey Tabaka2251d822017-04-20 16:04:07 -0700200 : surface(surface) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800201
Corey Tabaka2251d822017-04-20 16:04:07 -0700202 // Attempts to acquire a new buffer from the surface and return a tuple with
203 // width, height, buffer handle, and fence. If a new buffer is not available
204 // the previous buffer is returned or an empty value if no buffer has ever
205 // been posted. When a new buffer is acquired the previous buffer's release
206 // fence is passed out automatically.
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700207 std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
208 Acquire() {
Corey Tabaka2251d822017-04-20 16:04:07 -0700209 if (surface->IsBufferAvailable()) {
210 acquired_buffer.Release(std::move(release_fence));
211 acquired_buffer = surface->AcquireCurrentBuffer();
212 ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
213 }
214 if (!acquired_buffer.IsEmpty()) {
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700215 return std::make_tuple(
216 acquired_buffer.buffer()->width(),
217 acquired_buffer.buffer()->height(), acquired_buffer.buffer()->id(),
218 acquired_buffer.buffer()->buffer()->buffer(),
219 acquired_buffer.ClaimAcquireFence(), acquired_buffer.slot());
Corey Tabaka2251d822017-04-20 16:04:07 -0700220 } else {
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700221 return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700222 }
223 }
224
225 void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
226
227 // Gets a pointer to the current acquired buffer or returns nullptr if there
228 // isn't one.
229 IonBuffer* GetBuffer() {
230 if (acquired_buffer.IsAvailable())
231 return acquired_buffer.buffer()->buffer();
232 else
233 return nullptr;
234 }
235
236 // Returns the surface id of the surface.
Corey Tabaka0b485c92017-05-19 12:02:58 -0700237 int GetSurfaceId() const { return surface->surface_id(); }
238
239 // Returns the buffer id for the current buffer.
240 int GetBufferId() const {
241 if (acquired_buffer.IsAvailable())
242 return acquired_buffer.buffer()->id();
243 else
244 return -1;
245 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700246 };
247
248 // State when the layer is connected to a buffer. Provides the same interface
249 // as SourceSurface to simplify internal use by Layer.
250 struct SourceBuffer {
251 std::shared_ptr<IonBuffer> buffer;
252
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700253 std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
254 Acquire() {
Corey Tabaka2251d822017-04-20 16:04:07 -0700255 if (buffer)
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700256 return std::make_tuple(buffer->width(), buffer->height(), -1,
257 buffer->buffer(), pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700258 else
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700259 return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700260 }
261
262 void Finish(pdx::LocalHandle /*fence*/) {}
263
264 IonBuffer* GetBuffer() { return buffer.get(); }
265
266 int GetSurfaceId() const { return -1; }
Corey Tabaka0b485c92017-05-19 12:02:58 -0700267 int GetBufferId() const { return -1; }
Corey Tabaka2251d822017-04-20 16:04:07 -0700268 };
269
270 // The underlying hardware composer layer is supplied buffers either from a
271 // surface buffer train or from a buffer directly.
272 pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
273
274 pdx::LocalHandle acquire_fence_;
275 bool surface_rect_functions_applied_ = false;
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700276 bool pending_visibility_settings_ = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800277
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700278 // Map of buffer slot assignments that have already been established with HWC:
279 // slot -> buffer_id. When this map contains a matching slot and buffer_id the
280 // buffer argument to setLayerBuffer may be nullptr to avoid the cost of
281 // importing a buffer HWC already knows about.
282 std::map<std::size_t, int> cached_buffer_map_;
283
Steven Thomasbfe46a02018-02-16 14:27:35 -0800284 // When calling destroyLayer() on an external display that's been removed we
285 // typically get HWC2_ERROR_BAD_DISPLAY errors. If
286 // ignore_bad_display_errors_on_destroy_ is true, don't log the bad display
287 // errors, since they're expected.
288 bool ignore_bad_display_errors_on_destroy_ = false;
289
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800290 Layer(const Layer&) = delete;
291 void operator=(const Layer&) = delete;
292};
293
294// HardwareComposer encapsulates the hardware composer HAL, exposing a
295// simplified API to post buffers to the display.
Steven Thomas050b2c82017-03-06 11:45:16 -0800296//
297// HardwareComposer is accessed by both the vr flinger dispatcher thread and the
298// surface flinger main thread, in addition to internally running a separate
299// thread for compositing/EDS and posting layers to the HAL. When changing how
300// variables are used or adding new state think carefully about which threads
301// will access the state and whether it needs to be synchronized.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800302class HardwareComposer {
303 public:
Corey Tabaka2251d822017-04-20 16:04:07 -0700304 using RequestDisplayCallback = std::function<void(bool)>;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800305
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800306 HardwareComposer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800307 ~HardwareComposer();
308
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700309 bool Initialize(Hwc2::Composer* composer,
Steven Thomas6e8f7062017-11-22 14:15:29 -0800310 hwc2_display_t primary_display_id,
Steven Thomasd7f49c52017-07-26 18:48:28 -0700311 RequestDisplayCallback request_display_callback);
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800312
313 bool IsInitialized() const { return initialized_; }
314
Steven Thomas050b2c82017-03-06 11:45:16 -0800315 // Start the post thread if there's work to do (i.e. visible layers). This
316 // should only be called from surface flinger's main thread.
317 void Enable();
318 // Pause the post thread, blocking until the post thread has signaled that
319 // it's paused. This should only be called from surface flinger's main thread.
320 void Disable();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800321
Steven Thomasaf336272018-01-04 17:36:47 -0800322 // Called on a binder thread.
323 void OnBootFinished();
324
Corey Tabaka2251d822017-04-20 16:04:07 -0700325 std::string Dump();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800326
Steven Thomasbfe46a02018-02-16 14:27:35 -0800327 const DisplayParams& GetPrimaryDisplayParams() const {
328 return primary_display_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800329 }
330
Corey Tabaka2251d822017-04-20 16:04:07 -0700331 // Sets the display surfaces to compose the hardware layer stack.
Steven Thomas050b2c82017-03-06 11:45:16 -0800332 void SetDisplaySurfaces(
Corey Tabaka2251d822017-04-20 16:04:07 -0700333 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800334
John Bates954796e2017-05-11 11:00:31 -0700335 int OnNewGlobalBuffer(DvrGlobalBufferKey key, IonBuffer& ion_buffer);
336 void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);
337
mamik913cc132019-09-13 14:58:43 -0700338 // Gets the edid data for the current active display (internal or external)
339 DisplayIdentificationData GetCurrentDisplayIdentificationData() {
340 return display_identification_data_;
341 }
342
343 // Gets the edid port for the current active display (internal or external)
344 uint8_t GetCurrentDisplayPort() { return display_port_; }
345
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800346 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800347 DisplayParams GetDisplayParams(Hwc2::Composer* composer,
348 hwc2_display_t display, bool is_primary);
Steven Thomasd7f49c52017-07-26 18:48:28 -0700349
Steven Thomasbfe46a02018-02-16 14:27:35 -0800350 // Turn display vsync on/off. Returns true on success, false on failure.
351 bool EnableVsync(const DisplayParams& display, bool enabled);
352 // Turn display power on/off. Returns true on success, false on failure.
353 bool SetPowerMode(const DisplayParams& display, bool active);
354 // Convenience function to turn a display on/off. Turns both power and vsync
355 // on/off. Returns true on success, false on failure.
356 bool EnableDisplay(const DisplayParams& display, bool enabled);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800357
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700358 class VsyncService : public BnVsyncService {
359 public:
360 status_t registerCallback(const sp<IVsyncCallback> callback) override;
361 status_t unregisterCallback(const sp<IVsyncCallback> callback) override;
362 void OnVsync(int64_t vsync_timestamp);
363 private:
364 std::vector<sp<IVsyncCallback>>::const_iterator FindCallback(
365 const sp<IVsyncCallback>& callback) const;
366 std::mutex mutex_;
367 std::vector<sp<IVsyncCallback>> callbacks_;
368 };
369
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800370 class ComposerCallback : public Hwc2::IComposerCallback {
371 public:
Corey Tabakab3732f02017-09-16 00:58:54 -0700372 ComposerCallback() = default;
Steven Thomasd7f49c52017-07-26 18:48:28 -0700373 hardware::Return<void> onHotplug(Hwc2::Display display,
374 Connection conn) override;
375 hardware::Return<void> onRefresh(Hwc2::Display display) override;
376 hardware::Return<void> onVsync(Hwc2::Display display,
377 int64_t timestamp) override;
Ady Abraham7159f572019-10-11 11:10:18 -0700378 hardware::Return<void> onVsync_2_4(
379 Hwc2::Display display, int64_t timestamp,
380 Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override;
381 hardware::Return<void> onVsyncPeriodTimingChanged(
382 Hwc2::Display display,
383 const Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override;
Ady Abrahamb0433bc2020-01-08 17:31:06 -0800384 hardware::Return<void> onSeamlessPossible(Hwc2::Display display) override;
Corey Tabakab3732f02017-09-16 00:58:54 -0700385
Steven Thomasbfe46a02018-02-16 14:27:35 -0800386 bool GotFirstHotplug() { return got_first_hotplug_; }
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700387 void SetVsyncService(const sp<VsyncService>& vsync_service);
Steven Thomasbfe46a02018-02-16 14:27:35 -0800388
389 struct Displays {
390 hwc2_display_t primary_display = 0;
391 std::optional<hwc2_display_t> external_display;
392 bool external_display_was_hotplugged = false;
393 };
394
395 Displays GetDisplays();
396 pdx::Status<int64_t> GetVsyncTime(hwc2_display_t display);
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700397
Steven Thomasd7f49c52017-07-26 18:48:28 -0700398 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800399 struct DisplayInfo {
400 hwc2_display_t id = 0;
401 pdx::LocalHandle driver_vsync_event_fd;
402 int64_t callback_vsync_timestamp{0};
403 };
404
405 DisplayInfo* GetDisplayInfo(hwc2_display_t display);
406
407 std::mutex mutex_;
408
409 bool got_first_hotplug_ = false;
410 DisplayInfo primary_display_;
411 std::optional<DisplayInfo> external_display_;
412 bool external_display_was_hotplugged_ = false;
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700413 sp<VsyncService> vsync_service_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800414 };
415
Corey Tabaka2251d822017-04-20 16:04:07 -0700416 HWC::Error Validate(hwc2_display_t display);
417 HWC::Error Present(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800418
Steven Thomasbfe46a02018-02-16 14:27:35 -0800419 void PostLayers(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800420 void PostThread();
421
Corey Tabaka2251d822017-04-20 16:04:07 -0700422 // The post thread has two controlling states:
423 // 1. Idle: no work to do (no visible surfaces).
424 // 2. Suspended: explicitly halted (system is not in VR mode).
425 // When either #1 or #2 is true then the post thread is quiescent, otherwise
426 // it is active.
427 using PostThreadStateType = uint32_t;
428 struct PostThreadState {
429 enum : PostThreadStateType {
430 Active = 0,
431 Idle = (1 << 0),
432 Suspended = (1 << 1),
433 Quit = (1 << 2),
434 };
435 };
436
437 void UpdatePostThreadState(uint32_t state, bool suspend);
438
Steven Thomas050b2c82017-03-06 11:45:16 -0800439 // Blocks until either event_fd becomes readable, or we're interrupted by a
Steven Thomasd7f49c52017-07-26 18:48:28 -0700440 // control thread, or timeout_ms is reached before any events occur. Any
441 // errors are returned as negative errno values, with -ETIMEDOUT returned in
442 // the case of a timeout. If we're interrupted, kPostThreadInterrupted will be
443 // returned.
Corey Tabaka2251d822017-04-20 16:04:07 -0700444 int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700445 int requested_events, int timeout_ms);
Steven Thomas050b2c82017-03-06 11:45:16 -0800446
Steven Thomasbfe46a02018-02-16 14:27:35 -0800447 // WaitForPredictedVSync and SleepUntil are blocking calls made on the post
448 // thread that can be interrupted by a control thread. If interrupted, these
449 // calls return kPostThreadInterrupted.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800450 int ReadWaitPPState();
Steven Thomasbfe46a02018-02-16 14:27:35 -0800451 pdx::Status<int64_t> WaitForPredictedVSync();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800452 int SleepUntil(int64_t wakeup_timestamp);
453
Steven Thomasbfe46a02018-02-16 14:27:35 -0800454 // Initialize any newly connected displays, and set target_display_ to the
455 // display we should render to. Returns true if target_display_
456 // changed. Called only from the post thread.
457 bool UpdateTargetDisplay();
458
Corey Tabaka2251d822017-04-20 16:04:07 -0700459 // Reconfigures the layer stack if the display surfaces changed since the last
460 // frame. Called only from the post thread.
Steven Thomasbfe46a02018-02-16 14:27:35 -0800461 void UpdateLayerConfig();
462
463 // Called on the post thread to create the Composer instance.
464 void CreateComposer();
Steven Thomas050b2c82017-03-06 11:45:16 -0800465
466 // Called on the post thread when the post thread is resumed.
467 void OnPostThreadResumed();
468 // Called on the post thread when the post thread is paused or quits.
469 void OnPostThreadPaused();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800470
Steven Thomasaf336272018-01-04 17:36:47 -0800471 // Use post_thread_wait_ to wait for a specific condition, specified by pred.
472 // timeout_sec < 0 means wait indefinitely, otherwise it specifies the timeout
473 // in seconds.
474 // The lock must be held when this function is called.
475 // Returns true if the wait was interrupted because the post thread was asked
476 // to quit.
477 bool PostThreadCondWait(std::unique_lock<std::mutex>& lock,
478 int timeout_sec,
479 const std::function<bool()>& pred);
480
John Bates954796e2017-05-11 11:00:31 -0700481 // Map the given shared memory buffer to our broadcast ring to track updates
482 // to the config parameters.
483 int MapConfigBuffer(IonBuffer& ion_buffer);
484 void ConfigBufferDeleted();
485 // Poll for config udpates.
486 void UpdateConfigBuffer();
487
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800488 bool initialized_;
Corey Tabaka7024b8f2017-08-22 11:59:15 -0700489 bool is_standalone_device_;
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800490
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700491 std::unique_ptr<Hwc2::Composer> composer_;
492 sp<ComposerCallback> composer_callback_;
Corey Tabaka2251d822017-04-20 16:04:07 -0700493 RequestDisplayCallback request_display_callback_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800494
Steven Thomasbfe46a02018-02-16 14:27:35 -0800495 DisplayParams primary_display_;
496 std::optional<DisplayParams> external_display_;
497 DisplayParams* target_display_ = &primary_display_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800498
Steven Thomasbfe46a02018-02-16 14:27:35 -0800499 // The list of surfaces we should draw. Set by the display service when
500 // DirectSurfaces are added, removed, or change visibility. Written by the
501 // message dispatch thread and read by the post thread.
502 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces_;
503 // Set to true by the dispatch thread whenever surfaces_ changes. Set to false
504 // by the post thread when the new list of surfaces is processed.
505 bool surfaces_changed_ = false;
506
507 std::vector<std::shared_ptr<DirectDisplaySurface>> current_surfaces_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800508
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700509 // Layer set for handling buffer flow into hardware composer layers. This
510 // vector must be sorted by surface_id in ascending order.
511 std::vector<Layer> layers_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800512
Steven Thomas282a5ed2017-02-07 18:07:01 -0800513 // The layer posting thread. This thread wakes up a short time before vsync to
Corey Tabaka2251d822017-04-20 16:04:07 -0700514 // hand buffers to hardware composer.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800515 std::thread post_thread_;
516
Corey Tabaka2251d822017-04-20 16:04:07 -0700517 // Post thread state machine and synchronization primitives.
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700518 PostThreadStateType post_thread_state_{PostThreadState::Idle |
519 PostThreadState::Suspended};
Corey Tabaka2251d822017-04-20 16:04:07 -0700520 std::atomic<bool> post_thread_quiescent_{true};
521 bool post_thread_resumed_{false};
522 pdx::LocalHandle post_thread_event_fd_;
523 std::mutex post_thread_mutex_;
524 std::condition_variable post_thread_wait_;
525 std::condition_variable post_thread_ready_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800526
Steven Thomasaf336272018-01-04 17:36:47 -0800527 // When boot is finished this will be set to true and the post thread will be
528 // notified via post_thread_wait_.
529 bool boot_finished_ = false;
530
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800531 // VSync sleep timerfd.
532 pdx::LocalHandle vsync_sleep_timer_fd_;
533
534 // The timestamp of the last vsync.
Corey Tabaka2251d822017-04-20 16:04:07 -0700535 int64_t last_vsync_timestamp_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800536
Corey Tabakab3732f02017-09-16 00:58:54 -0700537 // The number of vsync intervals to predict since the last vsync.
538 int vsync_prediction_interval_ = 1;
539
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800540 // Vsync count since display on.
Corey Tabaka2251d822017-04-20 16:04:07 -0700541 uint32_t vsync_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800542
543 // Counter tracking the number of skipped frames.
Corey Tabaka2251d822017-04-20 16:04:07 -0700544 int frame_skip_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800545
546 // Fd array for tracking retire fences that are returned by hwc. This allows
547 // us to detect when the display driver begins queuing frames.
548 std::vector<pdx::LocalHandle> retire_fence_fds_;
549
Okan Arikan822b7102017-05-08 13:31:34 -0700550 // If we are publishing vsync data, we will put it here.
551 std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800552
John Bates954796e2017-05-11 11:00:31 -0700553 // Broadcast ring for receiving config data from the DisplayManager.
Okan Arikan6f468c62017-05-31 14:48:30 -0700554 DvrConfigRing shared_config_ring_;
John Bates954796e2017-05-11 11:00:31 -0700555 uint32_t shared_config_ring_sequence_{0};
556 // Config buffer for reading from the post thread.
Okan Arikan6f468c62017-05-31 14:48:30 -0700557 DvrConfig post_thread_config_;
John Bates954796e2017-05-11 11:00:31 -0700558 std::mutex shared_config_mutex_;
559
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700560 bool vsync_trace_parity_ = false;
561 sp<VsyncService> vsync_service_;
562
mamik913cc132019-09-13 14:58:43 -0700563 // Edid section.
564 void UpdateEdidData(Hwc2::Composer* composer, hwc2_display_t hw_id);
565 DisplayIdentificationData display_identification_data_;
566 uint8_t display_port_;
567
Steven Thomas050b2c82017-03-06 11:45:16 -0800568 static constexpr int kPostThreadInterrupted = 1;
569
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800570 HardwareComposer(const HardwareComposer&) = delete;
571 void operator=(const HardwareComposer&) = delete;
572};
573
574} // namespace dvr
575} // namespace android
576
577#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_