blob: 80fa7acf1764e9f2160f1a4fb67d46dbc7c1b413 [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>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080025#include <private/dvr/buffer_hub_client.h>
Okan Arikan822b7102017-05-08 13:31:34 -070026#include <private/dvr/shared_buffer_helpers.h>
Steven Thomasdfde8fa2018-04-19 16:00:58 -070027#include <private/dvr/vsync_service.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080028
29#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
90 Layer(Layer&&);
91 Layer& operator=(Layer&&);
92
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
Corey Tabaka2251d822017-04-20 16:04:07 -0700199 SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
200 : 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
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800338 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800339 DisplayParams GetDisplayParams(Hwc2::Composer* composer,
340 hwc2_display_t display, bool is_primary);
Steven Thomasd7f49c52017-07-26 18:48:28 -0700341
Steven Thomasbfe46a02018-02-16 14:27:35 -0800342 // Turn display vsync on/off. Returns true on success, false on failure.
343 bool EnableVsync(const DisplayParams& display, bool enabled);
344 // Turn display power on/off. Returns true on success, false on failure.
345 bool SetPowerMode(const DisplayParams& display, bool active);
346 // Convenience function to turn a display on/off. Turns both power and vsync
347 // on/off. Returns true on success, false on failure.
348 bool EnableDisplay(const DisplayParams& display, bool enabled);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800349
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700350 class VsyncService : public BnVsyncService {
351 public:
352 status_t registerCallback(const sp<IVsyncCallback> callback) override;
353 status_t unregisterCallback(const sp<IVsyncCallback> callback) override;
354 void OnVsync(int64_t vsync_timestamp);
355 private:
356 std::vector<sp<IVsyncCallback>>::const_iterator FindCallback(
357 const sp<IVsyncCallback>& callback) const;
358 std::mutex mutex_;
359 std::vector<sp<IVsyncCallback>> callbacks_;
360 };
361
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800362 class ComposerCallback : public Hwc2::IComposerCallback {
363 public:
Corey Tabakab3732f02017-09-16 00:58:54 -0700364 ComposerCallback() = default;
Steven Thomasd7f49c52017-07-26 18:48:28 -0700365 hardware::Return<void> onHotplug(Hwc2::Display display,
366 Connection conn) override;
367 hardware::Return<void> onRefresh(Hwc2::Display display) override;
368 hardware::Return<void> onVsync(Hwc2::Display display,
369 int64_t timestamp) override;
Corey Tabakab3732f02017-09-16 00:58:54 -0700370
Steven Thomasbfe46a02018-02-16 14:27:35 -0800371 bool GotFirstHotplug() { return got_first_hotplug_; }
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700372 void SetVsyncService(const sp<VsyncService>& vsync_service);
Steven Thomasbfe46a02018-02-16 14:27:35 -0800373
374 struct Displays {
375 hwc2_display_t primary_display = 0;
376 std::optional<hwc2_display_t> external_display;
377 bool external_display_was_hotplugged = false;
378 };
379
380 Displays GetDisplays();
381 pdx::Status<int64_t> GetVsyncTime(hwc2_display_t display);
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700382
Steven Thomasd7f49c52017-07-26 18:48:28 -0700383 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800384 struct DisplayInfo {
385 hwc2_display_t id = 0;
386 pdx::LocalHandle driver_vsync_event_fd;
387 int64_t callback_vsync_timestamp{0};
388 };
389
390 DisplayInfo* GetDisplayInfo(hwc2_display_t display);
391
392 std::mutex mutex_;
393
394 bool got_first_hotplug_ = false;
395 DisplayInfo primary_display_;
396 std::optional<DisplayInfo> external_display_;
397 bool external_display_was_hotplugged_ = false;
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700398 sp<VsyncService> vsync_service_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800399 };
400
Corey Tabaka2251d822017-04-20 16:04:07 -0700401 HWC::Error Validate(hwc2_display_t display);
402 HWC::Error Present(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800403
Steven Thomasbfe46a02018-02-16 14:27:35 -0800404 void PostLayers(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800405 void PostThread();
406
Corey Tabaka2251d822017-04-20 16:04:07 -0700407 // The post thread has two controlling states:
408 // 1. Idle: no work to do (no visible surfaces).
409 // 2. Suspended: explicitly halted (system is not in VR mode).
410 // When either #1 or #2 is true then the post thread is quiescent, otherwise
411 // it is active.
412 using PostThreadStateType = uint32_t;
413 struct PostThreadState {
414 enum : PostThreadStateType {
415 Active = 0,
416 Idle = (1 << 0),
417 Suspended = (1 << 1),
418 Quit = (1 << 2),
419 };
420 };
421
422 void UpdatePostThreadState(uint32_t state, bool suspend);
423
Steven Thomas050b2c82017-03-06 11:45:16 -0800424 // Blocks until either event_fd becomes readable, or we're interrupted by a
Steven Thomasd7f49c52017-07-26 18:48:28 -0700425 // control thread, or timeout_ms is reached before any events occur. Any
426 // errors are returned as negative errno values, with -ETIMEDOUT returned in
427 // the case of a timeout. If we're interrupted, kPostThreadInterrupted will be
428 // returned.
Corey Tabaka2251d822017-04-20 16:04:07 -0700429 int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700430 int requested_events, int timeout_ms);
Steven Thomas050b2c82017-03-06 11:45:16 -0800431
Steven Thomasbfe46a02018-02-16 14:27:35 -0800432 // WaitForPredictedVSync and SleepUntil are blocking calls made on the post
433 // thread that can be interrupted by a control thread. If interrupted, these
434 // calls return kPostThreadInterrupted.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800435 int ReadWaitPPState();
Steven Thomasbfe46a02018-02-16 14:27:35 -0800436 pdx::Status<int64_t> WaitForPredictedVSync();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800437 int SleepUntil(int64_t wakeup_timestamp);
438
Steven Thomasbfe46a02018-02-16 14:27:35 -0800439 // Initialize any newly connected displays, and set target_display_ to the
440 // display we should render to. Returns true if target_display_
441 // changed. Called only from the post thread.
442 bool UpdateTargetDisplay();
443
Corey Tabaka2251d822017-04-20 16:04:07 -0700444 // Reconfigures the layer stack if the display surfaces changed since the last
445 // frame. Called only from the post thread.
Steven Thomasbfe46a02018-02-16 14:27:35 -0800446 void UpdateLayerConfig();
447
448 // Called on the post thread to create the Composer instance.
449 void CreateComposer();
Steven Thomas050b2c82017-03-06 11:45:16 -0800450
451 // Called on the post thread when the post thread is resumed.
452 void OnPostThreadResumed();
453 // Called on the post thread when the post thread is paused or quits.
454 void OnPostThreadPaused();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800455
Steven Thomasaf336272018-01-04 17:36:47 -0800456 // Use post_thread_wait_ to wait for a specific condition, specified by pred.
457 // timeout_sec < 0 means wait indefinitely, otherwise it specifies the timeout
458 // in seconds.
459 // The lock must be held when this function is called.
460 // Returns true if the wait was interrupted because the post thread was asked
461 // to quit.
462 bool PostThreadCondWait(std::unique_lock<std::mutex>& lock,
463 int timeout_sec,
464 const std::function<bool()>& pred);
465
John Bates954796e2017-05-11 11:00:31 -0700466 // Map the given shared memory buffer to our broadcast ring to track updates
467 // to the config parameters.
468 int MapConfigBuffer(IonBuffer& ion_buffer);
469 void ConfigBufferDeleted();
470 // Poll for config udpates.
471 void UpdateConfigBuffer();
472
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800473 bool initialized_;
Corey Tabaka7024b8f2017-08-22 11:59:15 -0700474 bool is_standalone_device_;
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800475
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700476 std::unique_ptr<Hwc2::Composer> composer_;
477 sp<ComposerCallback> composer_callback_;
Corey Tabaka2251d822017-04-20 16:04:07 -0700478 RequestDisplayCallback request_display_callback_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800479
Steven Thomasbfe46a02018-02-16 14:27:35 -0800480 DisplayParams primary_display_;
481 std::optional<DisplayParams> external_display_;
482 DisplayParams* target_display_ = &primary_display_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800483
Steven Thomasbfe46a02018-02-16 14:27:35 -0800484 // The list of surfaces we should draw. Set by the display service when
485 // DirectSurfaces are added, removed, or change visibility. Written by the
486 // message dispatch thread and read by the post thread.
487 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces_;
488 // Set to true by the dispatch thread whenever surfaces_ changes. Set to false
489 // by the post thread when the new list of surfaces is processed.
490 bool surfaces_changed_ = false;
491
492 std::vector<std::shared_ptr<DirectDisplaySurface>> current_surfaces_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800493
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700494 // Layer set for handling buffer flow into hardware composer layers. This
495 // vector must be sorted by surface_id in ascending order.
496 std::vector<Layer> layers_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800497
Steven Thomas282a5ed2017-02-07 18:07:01 -0800498 // The layer posting thread. This thread wakes up a short time before vsync to
Corey Tabaka2251d822017-04-20 16:04:07 -0700499 // hand buffers to hardware composer.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800500 std::thread post_thread_;
501
Corey Tabaka2251d822017-04-20 16:04:07 -0700502 // Post thread state machine and synchronization primitives.
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700503 PostThreadStateType post_thread_state_{PostThreadState::Idle |
504 PostThreadState::Suspended};
Corey Tabaka2251d822017-04-20 16:04:07 -0700505 std::atomic<bool> post_thread_quiescent_{true};
506 bool post_thread_resumed_{false};
507 pdx::LocalHandle post_thread_event_fd_;
508 std::mutex post_thread_mutex_;
509 std::condition_variable post_thread_wait_;
510 std::condition_variable post_thread_ready_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800511
Steven Thomasaf336272018-01-04 17:36:47 -0800512 // When boot is finished this will be set to true and the post thread will be
513 // notified via post_thread_wait_.
514 bool boot_finished_ = false;
515
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800516 // VSync sleep timerfd.
517 pdx::LocalHandle vsync_sleep_timer_fd_;
518
519 // The timestamp of the last vsync.
Corey Tabaka2251d822017-04-20 16:04:07 -0700520 int64_t last_vsync_timestamp_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800521
Corey Tabakab3732f02017-09-16 00:58:54 -0700522 // The number of vsync intervals to predict since the last vsync.
523 int vsync_prediction_interval_ = 1;
524
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800525 // Vsync count since display on.
Corey Tabaka2251d822017-04-20 16:04:07 -0700526 uint32_t vsync_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800527
528 // Counter tracking the number of skipped frames.
Corey Tabaka2251d822017-04-20 16:04:07 -0700529 int frame_skip_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800530
531 // Fd array for tracking retire fences that are returned by hwc. This allows
532 // us to detect when the display driver begins queuing frames.
533 std::vector<pdx::LocalHandle> retire_fence_fds_;
534
Okan Arikan822b7102017-05-08 13:31:34 -0700535 // If we are publishing vsync data, we will put it here.
536 std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800537
John Bates954796e2017-05-11 11:00:31 -0700538 // Broadcast ring for receiving config data from the DisplayManager.
Okan Arikan6f468c62017-05-31 14:48:30 -0700539 DvrConfigRing shared_config_ring_;
John Bates954796e2017-05-11 11:00:31 -0700540 uint32_t shared_config_ring_sequence_{0};
541 // Config buffer for reading from the post thread.
Okan Arikan6f468c62017-05-31 14:48:30 -0700542 DvrConfig post_thread_config_;
John Bates954796e2017-05-11 11:00:31 -0700543 std::mutex shared_config_mutex_;
544
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700545 bool vsync_trace_parity_ = false;
546 sp<VsyncService> vsync_service_;
547
Steven Thomas050b2c82017-03-06 11:45:16 -0800548 static constexpr int kPostThreadInterrupted = 1;
549
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800550 HardwareComposer(const HardwareComposer&) = delete;
551 void operator=(const HardwareComposer&) = delete;
552};
553
554} // namespace dvr
555} // namespace android
556
557#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_