blob: db0d6a7670d5606606211c07ec3431af017a4d2d [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
28#include "acquired_buffer.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080029#include "display_surface.h"
30
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080031// 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
36namespace android {
37namespace dvr {
38
Steven Thomasbfe46a02018-02-16 14:27:35 -080039// Basic display metrics for physical displays.
40struct DisplayParams {
41 hwc2_display_t id;
42 bool is_primary;
43
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080044 int width;
45 int height;
Steven Thomasbfe46a02018-02-16 14:27:35 -080046
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080047 struct {
48 int x;
49 int y;
50 } dpi;
Steven Thomasbfe46a02018-02-16 14:27:35 -080051
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080052 int vsync_period_ns;
53};
54
55// Layer represents the connection between a hardware composer layer and the
56// source supplying buffers for the layer's contents.
57class Layer {
58 public:
Corey Tabaka2c4aea32017-08-31 20:01:15 -070059 Layer() = default;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080060
61 // Sets up the layer to use a display surface as its content source. The Layer
Corey Tabaka2251d822017-04-20 16:04:07 -070062 // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
63 // every frame.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080064 //
Steven Thomasbfe46a02018-02-16 14:27:35 -080065 // |composer| The composer instance.
66 // |display_params| Info about the display to use.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080067 // |blending| receives HWC_BLENDING_* values.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080068 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
69 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Corey Tabaka2251d822017-04-20 16:04:07 -070070 // |index| is the index of this surface in the DirectDisplaySurface array.
Steven Thomasbfe46a02018-02-16 14:27:35 -080071 Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
72 const std::shared_ptr<DirectDisplaySurface>& surface,
73 HWC::BlendMode blending, HWC::Composition composition_type,
74 size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080075
76 // Sets up the layer to use a direct buffer as its content source. No special
77 // handling of the buffer is performed; responsibility for updating or
78 // changing the buffer each frame is on the caller.
79 //
Steven Thomasbfe46a02018-02-16 14:27:35 -080080 // |composer| The composer instance.
81 // |display_params| Info about the display to use.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080082 // |blending| receives HWC_BLENDING_* values.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080083 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
84 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Steven Thomasbfe46a02018-02-16 14:27:35 -080085 Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
86 const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
87 HWC::Composition composition_type, size_t z_order);
Corey Tabaka2c4aea32017-08-31 20:01:15 -070088
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070089 Layer(Layer&&) noexcept;
90 Layer& operator=(Layer&&) noexcept;
Corey Tabaka2c4aea32017-08-31 20:01:15 -070091
92 ~Layer();
93
94 // Releases any shared pointers and fence handles held by this instance.
95 void Reset();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080096
97 // Layers that use a direct IonBuffer should call this each frame to update
98 // which buffer will be used for the next PostLayers.
Corey Tabaka2251d822017-04-20 16:04:07 -070099 void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800100
101 // Sets up the hardware composer layer for the next frame. When the layer is
102 // associated with a display surface, this method automatically ACQUIRES a new
103 // buffer if one is available.
104 void Prepare();
105
106 // After calling prepare, if this frame is to be dropped instead of passing
107 // along to the HWC, call Drop to close the contained fence(s).
108 void Drop();
109
110 // Performs fence bookkeeping after the frame has been posted to hardware
111 // composer.
112 void Finish(int release_fence_fd);
113
114 // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
Corey Tabaka2251d822017-04-20 16:04:07 -0700115 void SetBlending(HWC::BlendMode blending);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800116
Corey Tabaka2251d822017-04-20 16:04:07 -0700117 // Sets the z-order of this layer
118 void SetZOrder(size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800119
120 // Gets the current IonBuffer associated with this layer. Ownership of the
121 // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
122 // remain valid across calls to Layer::Setup(), Layer::Prepare(), or
123 // Layer::Reset(). YOU HAVE BEEN WARNED.
124 IonBuffer* GetBuffer();
125
Corey Tabaka2251d822017-04-20 16:04:07 -0700126 HWC::Composition GetCompositionType() const { return composition_type_; }
127 HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
128 bool IsLayerSetup() const { return !source_.empty(); }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800129
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800130 int GetSurfaceId() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700131 int surface_id = -1;
132 pdx::rpc::IfAnyOf<SourceSurface>::Call(
133 &source_, [&surface_id](const SourceSurface& surface_source) {
Corey Tabaka0b485c92017-05-19 12:02:58 -0700134 surface_id = surface_source.GetSurfaceId();
Corey Tabaka2251d822017-04-20 16:04:07 -0700135 });
136 return surface_id;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800137 }
138
Corey Tabaka0b485c92017-05-19 12:02:58 -0700139 int GetBufferId() const {
140 int buffer_id = -1;
141 pdx::rpc::IfAnyOf<SourceSurface>::Call(
142 &source_, [&buffer_id](const SourceSurface& surface_source) {
143 buffer_id = surface_source.GetBufferId();
144 });
145 return buffer_id;
146 }
147
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700148 // Compares Layers by surface id.
149 bool operator<(const Layer& other) const {
150 return GetSurfaceId() < other.GetSurfaceId();
151 }
Corey Tabakab3732f02017-09-16 00:58:54 -0700152 bool operator<(int surface_id) const { return GetSurfaceId() < surface_id; }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800153
Steven Thomasbfe46a02018-02-16 14:27:35 -0800154 void IgnoreBadDisplayErrorsOnDestroy(bool ignore) {
155 ignore_bad_display_errors_on_destroy_ = ignore;
Steven Thomas6e8f7062017-11-22 14:15:29 -0800156 }
157
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700158 private:
159 void CommonLayerSetup();
160
161 // Applies all of the settings to this layer using the hwc functions
162 void UpdateLayerSettings();
163
164 // Applies visibility settings that may have changed.
165 void UpdateVisibilitySettings();
166
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700167 // Checks whether the buffer, given by id, is associated with the given slot
168 // in the HWC buffer cache. If the slot is not associated with the given
169 // buffer the cache is updated to establish the association and the buffer
170 // should be sent to HWC using setLayerBuffer. Returns true if the association
171 // was already established, false if not. A buffer_id of -1 is never
172 // associated and always returns false.
173 bool CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id);
174
Steven Thomasbfe46a02018-02-16 14:27:35 -0800175 // Composer instance.
176 Hwc2::Composer* composer_ = nullptr;
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700177
Steven Thomasbfe46a02018-02-16 14:27:35 -0800178 // Parameters of the display to use for this layer.
179 DisplayParams display_params_;
Steven Thomas6e8f7062017-11-22 14:15:29 -0800180
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800181 // The hardware composer layer and metrics to use during the prepare cycle.
Corey Tabaka2251d822017-04-20 16:04:07 -0700182 hwc2_layer_t hardware_composer_layer_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800183
184 // Layer properties used to setup the hardware composer layer during the
185 // Prepare phase.
Corey Tabaka2251d822017-04-20 16:04:07 -0700186 size_t z_order_ = 0;
187 HWC::BlendMode blending_ = HWC::BlendMode::None;
Corey Tabaka2251d822017-04-20 16:04:07 -0700188 HWC::Composition composition_type_ = HWC::Composition::Invalid;
189 HWC::Composition target_composition_type_ = HWC::Composition::Device;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800190
Corey Tabaka2251d822017-04-20 16:04:07 -0700191 // State when the layer is connected to a surface. Provides the same interface
192 // as SourceBuffer to simplify internal use by Layer.
193 struct SourceSurface {
194 std::shared_ptr<DirectDisplaySurface> surface;
195 AcquiredBuffer acquired_buffer;
196 pdx::LocalHandle release_fence;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800197
Chih-Hung Hsieh79e7f1b2018-12-20 15:53:43 -0800198 explicit SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
Corey Tabaka2251d822017-04-20 16:04:07 -0700199 : surface(surface) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800200
Corey Tabaka2251d822017-04-20 16:04:07 -0700201 // Attempts to acquire a new buffer from the surface and return a tuple with
202 // width, height, buffer handle, and fence. If a new buffer is not available
203 // the previous buffer is returned or an empty value if no buffer has ever
204 // been posted. When a new buffer is acquired the previous buffer's release
205 // fence is passed out automatically.
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700206 std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
207 Acquire() {
Corey Tabaka2251d822017-04-20 16:04:07 -0700208 if (surface->IsBufferAvailable()) {
209 acquired_buffer.Release(std::move(release_fence));
210 acquired_buffer = surface->AcquireCurrentBuffer();
211 ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
212 }
213 if (!acquired_buffer.IsEmpty()) {
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700214 return std::make_tuple(
215 acquired_buffer.buffer()->width(),
216 acquired_buffer.buffer()->height(), acquired_buffer.buffer()->id(),
217 acquired_buffer.buffer()->buffer()->buffer(),
218 acquired_buffer.ClaimAcquireFence(), acquired_buffer.slot());
Corey Tabaka2251d822017-04-20 16:04:07 -0700219 } else {
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700220 return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700221 }
222 }
223
224 void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
225
226 // Gets a pointer to the current acquired buffer or returns nullptr if there
227 // isn't one.
228 IonBuffer* GetBuffer() {
229 if (acquired_buffer.IsAvailable())
230 return acquired_buffer.buffer()->buffer();
231 else
232 return nullptr;
233 }
234
235 // Returns the surface id of the surface.
Corey Tabaka0b485c92017-05-19 12:02:58 -0700236 int GetSurfaceId() const { return surface->surface_id(); }
237
238 // Returns the buffer id for the current buffer.
239 int GetBufferId() const {
240 if (acquired_buffer.IsAvailable())
241 return acquired_buffer.buffer()->id();
242 else
243 return -1;
244 }
Corey Tabaka2251d822017-04-20 16:04:07 -0700245 };
246
247 // State when the layer is connected to a buffer. Provides the same interface
248 // as SourceSurface to simplify internal use by Layer.
249 struct SourceBuffer {
250 std::shared_ptr<IonBuffer> buffer;
251
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700252 std::tuple<int, int, int, sp<GraphicBuffer>, pdx::LocalHandle, std::size_t>
253 Acquire() {
Corey Tabaka2251d822017-04-20 16:04:07 -0700254 if (buffer)
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700255 return std::make_tuple(buffer->width(), buffer->height(), -1,
256 buffer->buffer(), pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700257 else
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700258 return std::make_tuple(0, 0, -1, nullptr, pdx::LocalHandle{}, 0);
Corey Tabaka2251d822017-04-20 16:04:07 -0700259 }
260
261 void Finish(pdx::LocalHandle /*fence*/) {}
262
263 IonBuffer* GetBuffer() { return buffer.get(); }
264
265 int GetSurfaceId() const { return -1; }
Corey Tabaka0b485c92017-05-19 12:02:58 -0700266 int GetBufferId() const { return -1; }
Corey Tabaka2251d822017-04-20 16:04:07 -0700267 };
268
269 // The underlying hardware composer layer is supplied buffers either from a
270 // surface buffer train or from a buffer directly.
271 pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
272
273 pdx::LocalHandle acquire_fence_;
274 bool surface_rect_functions_applied_ = false;
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700275 bool pending_visibility_settings_ = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800276
Corey Tabaka0d07cdd2017-09-28 11:15:50 -0700277 // Map of buffer slot assignments that have already been established with HWC:
278 // slot -> buffer_id. When this map contains a matching slot and buffer_id the
279 // buffer argument to setLayerBuffer may be nullptr to avoid the cost of
280 // importing a buffer HWC already knows about.
281 std::map<std::size_t, int> cached_buffer_map_;
282
Steven Thomasbfe46a02018-02-16 14:27:35 -0800283 // When calling destroyLayer() on an external display that's been removed we
284 // typically get HWC2_ERROR_BAD_DISPLAY errors. If
285 // ignore_bad_display_errors_on_destroy_ is true, don't log the bad display
286 // errors, since they're expected.
287 bool ignore_bad_display_errors_on_destroy_ = false;
288
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800289 Layer(const Layer&) = delete;
290 void operator=(const Layer&) = delete;
291};
292
293// HardwareComposer encapsulates the hardware composer HAL, exposing a
294// simplified API to post buffers to the display.
Steven Thomas050b2c82017-03-06 11:45:16 -0800295//
296// HardwareComposer is accessed by both the vr flinger dispatcher thread and the
297// surface flinger main thread, in addition to internally running a separate
298// thread for compositing/EDS and posting layers to the HAL. When changing how
299// variables are used or adding new state think carefully about which threads
300// will access the state and whether it needs to be synchronized.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800301class HardwareComposer {
302 public:
Corey Tabaka2251d822017-04-20 16:04:07 -0700303 using RequestDisplayCallback = std::function<void(bool)>;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800304
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800305 HardwareComposer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800306 ~HardwareComposer();
307
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700308 bool Initialize(Hwc2::Composer* composer,
Steven Thomas6e8f7062017-11-22 14:15:29 -0800309 hwc2_display_t primary_display_id,
Steven Thomasd7f49c52017-07-26 18:48:28 -0700310 RequestDisplayCallback request_display_callback);
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800311
312 bool IsInitialized() const { return initialized_; }
313
Steven Thomas050b2c82017-03-06 11:45:16 -0800314 // Start the post thread if there's work to do (i.e. visible layers). This
315 // should only be called from surface flinger's main thread.
316 void Enable();
317 // Pause the post thread, blocking until the post thread has signaled that
318 // it's paused. This should only be called from surface flinger's main thread.
319 void Disable();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800320
Steven Thomasaf336272018-01-04 17:36:47 -0800321 // Called on a binder thread.
322 void OnBootFinished();
323
Corey Tabaka2251d822017-04-20 16:04:07 -0700324 std::string Dump();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800325
Steven Thomasbfe46a02018-02-16 14:27:35 -0800326 const DisplayParams& GetPrimaryDisplayParams() const {
327 return primary_display_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800328 }
329
Corey Tabaka2251d822017-04-20 16:04:07 -0700330 // Sets the display surfaces to compose the hardware layer stack.
Steven Thomas050b2c82017-03-06 11:45:16 -0800331 void SetDisplaySurfaces(
Corey Tabaka2251d822017-04-20 16:04:07 -0700332 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800333
John Bates954796e2017-05-11 11:00:31 -0700334 int OnNewGlobalBuffer(DvrGlobalBufferKey key, IonBuffer& ion_buffer);
335 void OnDeletedGlobalBuffer(DvrGlobalBufferKey key);
336
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800337 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800338 DisplayParams GetDisplayParams(Hwc2::Composer* composer,
339 hwc2_display_t display, bool is_primary);
Steven Thomasd7f49c52017-07-26 18:48:28 -0700340
Steven Thomasbfe46a02018-02-16 14:27:35 -0800341 // Turn display vsync on/off. Returns true on success, false on failure.
342 bool EnableVsync(const DisplayParams& display, bool enabled);
343 // Turn display power on/off. Returns true on success, false on failure.
344 bool SetPowerMode(const DisplayParams& display, bool active);
345 // Convenience function to turn a display on/off. Turns both power and vsync
346 // on/off. Returns true on success, false on failure.
347 bool EnableDisplay(const DisplayParams& display, bool enabled);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800348
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700349 class VsyncService : public BnVsyncService {
350 public:
351 status_t registerCallback(const sp<IVsyncCallback> callback) override;
352 status_t unregisterCallback(const sp<IVsyncCallback> callback) override;
353 void OnVsync(int64_t vsync_timestamp);
354 private:
355 std::vector<sp<IVsyncCallback>>::const_iterator FindCallback(
356 const sp<IVsyncCallback>& callback) const;
357 std::mutex mutex_;
358 std::vector<sp<IVsyncCallback>> callbacks_;
359 };
360
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800361 class ComposerCallback : public Hwc2::IComposerCallback {
362 public:
Corey Tabakab3732f02017-09-16 00:58:54 -0700363 ComposerCallback() = default;
Steven Thomasd7f49c52017-07-26 18:48:28 -0700364 hardware::Return<void> onHotplug(Hwc2::Display display,
365 Connection conn) override;
366 hardware::Return<void> onRefresh(Hwc2::Display display) override;
367 hardware::Return<void> onVsync(Hwc2::Display display,
368 int64_t timestamp) override;
Corey Tabakab3732f02017-09-16 00:58:54 -0700369
Steven Thomasbfe46a02018-02-16 14:27:35 -0800370 bool GotFirstHotplug() { return got_first_hotplug_; }
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700371 void SetVsyncService(const sp<VsyncService>& vsync_service);
Steven Thomasbfe46a02018-02-16 14:27:35 -0800372
373 struct Displays {
374 hwc2_display_t primary_display = 0;
375 std::optional<hwc2_display_t> external_display;
376 bool external_display_was_hotplugged = false;
377 };
378
379 Displays GetDisplays();
380 pdx::Status<int64_t> GetVsyncTime(hwc2_display_t display);
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700381
Steven Thomasd7f49c52017-07-26 18:48:28 -0700382 private:
Steven Thomasbfe46a02018-02-16 14:27:35 -0800383 struct DisplayInfo {
384 hwc2_display_t id = 0;
385 pdx::LocalHandle driver_vsync_event_fd;
386 int64_t callback_vsync_timestamp{0};
387 };
388
389 DisplayInfo* GetDisplayInfo(hwc2_display_t display);
390
391 std::mutex mutex_;
392
393 bool got_first_hotplug_ = false;
394 DisplayInfo primary_display_;
395 std::optional<DisplayInfo> external_display_;
396 bool external_display_was_hotplugged_ = false;
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700397 sp<VsyncService> vsync_service_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800398 };
399
Corey Tabaka2251d822017-04-20 16:04:07 -0700400 HWC::Error Validate(hwc2_display_t display);
401 HWC::Error Present(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800402
Steven Thomasbfe46a02018-02-16 14:27:35 -0800403 void PostLayers(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800404 void PostThread();
405
Corey Tabaka2251d822017-04-20 16:04:07 -0700406 // The post thread has two controlling states:
407 // 1. Idle: no work to do (no visible surfaces).
408 // 2. Suspended: explicitly halted (system is not in VR mode).
409 // When either #1 or #2 is true then the post thread is quiescent, otherwise
410 // it is active.
411 using PostThreadStateType = uint32_t;
412 struct PostThreadState {
413 enum : PostThreadStateType {
414 Active = 0,
415 Idle = (1 << 0),
416 Suspended = (1 << 1),
417 Quit = (1 << 2),
418 };
419 };
420
421 void UpdatePostThreadState(uint32_t state, bool suspend);
422
Steven Thomas050b2c82017-03-06 11:45:16 -0800423 // Blocks until either event_fd becomes readable, or we're interrupted by a
Steven Thomasd7f49c52017-07-26 18:48:28 -0700424 // control thread, or timeout_ms is reached before any events occur. Any
425 // errors are returned as negative errno values, with -ETIMEDOUT returned in
426 // the case of a timeout. If we're interrupted, kPostThreadInterrupted will be
427 // returned.
Corey Tabaka2251d822017-04-20 16:04:07 -0700428 int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700429 int requested_events, int timeout_ms);
Steven Thomas050b2c82017-03-06 11:45:16 -0800430
Steven Thomasbfe46a02018-02-16 14:27:35 -0800431 // WaitForPredictedVSync and SleepUntil are blocking calls made on the post
432 // thread that can be interrupted by a control thread. If interrupted, these
433 // calls return kPostThreadInterrupted.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800434 int ReadWaitPPState();
Steven Thomasbfe46a02018-02-16 14:27:35 -0800435 pdx::Status<int64_t> WaitForPredictedVSync();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800436 int SleepUntil(int64_t wakeup_timestamp);
437
Steven Thomasbfe46a02018-02-16 14:27:35 -0800438 // Initialize any newly connected displays, and set target_display_ to the
439 // display we should render to. Returns true if target_display_
440 // changed. Called only from the post thread.
441 bool UpdateTargetDisplay();
442
Corey Tabaka2251d822017-04-20 16:04:07 -0700443 // Reconfigures the layer stack if the display surfaces changed since the last
444 // frame. Called only from the post thread.
Steven Thomasbfe46a02018-02-16 14:27:35 -0800445 void UpdateLayerConfig();
446
447 // Called on the post thread to create the Composer instance.
448 void CreateComposer();
Steven Thomas050b2c82017-03-06 11:45:16 -0800449
450 // Called on the post thread when the post thread is resumed.
451 void OnPostThreadResumed();
452 // Called on the post thread when the post thread is paused or quits.
453 void OnPostThreadPaused();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800454
Steven Thomasaf336272018-01-04 17:36:47 -0800455 // Use post_thread_wait_ to wait for a specific condition, specified by pred.
456 // timeout_sec < 0 means wait indefinitely, otherwise it specifies the timeout
457 // in seconds.
458 // The lock must be held when this function is called.
459 // Returns true if the wait was interrupted because the post thread was asked
460 // to quit.
461 bool PostThreadCondWait(std::unique_lock<std::mutex>& lock,
462 int timeout_sec,
463 const std::function<bool()>& pred);
464
John Bates954796e2017-05-11 11:00:31 -0700465 // Map the given shared memory buffer to our broadcast ring to track updates
466 // to the config parameters.
467 int MapConfigBuffer(IonBuffer& ion_buffer);
468 void ConfigBufferDeleted();
469 // Poll for config udpates.
470 void UpdateConfigBuffer();
471
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800472 bool initialized_;
Corey Tabaka7024b8f2017-08-22 11:59:15 -0700473 bool is_standalone_device_;
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800474
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700475 std::unique_ptr<Hwc2::Composer> composer_;
476 sp<ComposerCallback> composer_callback_;
Corey Tabaka2251d822017-04-20 16:04:07 -0700477 RequestDisplayCallback request_display_callback_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800478
Steven Thomasbfe46a02018-02-16 14:27:35 -0800479 DisplayParams primary_display_;
480 std::optional<DisplayParams> external_display_;
481 DisplayParams* target_display_ = &primary_display_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800482
Steven Thomasbfe46a02018-02-16 14:27:35 -0800483 // The list of surfaces we should draw. Set by the display service when
484 // DirectSurfaces are added, removed, or change visibility. Written by the
485 // message dispatch thread and read by the post thread.
486 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces_;
487 // Set to true by the dispatch thread whenever surfaces_ changes. Set to false
488 // by the post thread when the new list of surfaces is processed.
489 bool surfaces_changed_ = false;
490
491 std::vector<std::shared_ptr<DirectDisplaySurface>> current_surfaces_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800492
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700493 // Layer set for handling buffer flow into hardware composer layers. This
494 // vector must be sorted by surface_id in ascending order.
495 std::vector<Layer> layers_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800496
Steven Thomas282a5ed2017-02-07 18:07:01 -0800497 // The layer posting thread. This thread wakes up a short time before vsync to
Corey Tabaka2251d822017-04-20 16:04:07 -0700498 // hand buffers to hardware composer.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800499 std::thread post_thread_;
500
Corey Tabaka2251d822017-04-20 16:04:07 -0700501 // Post thread state machine and synchronization primitives.
Corey Tabaka2c4aea32017-08-31 20:01:15 -0700502 PostThreadStateType post_thread_state_{PostThreadState::Idle |
503 PostThreadState::Suspended};
Corey Tabaka2251d822017-04-20 16:04:07 -0700504 std::atomic<bool> post_thread_quiescent_{true};
505 bool post_thread_resumed_{false};
506 pdx::LocalHandle post_thread_event_fd_;
507 std::mutex post_thread_mutex_;
508 std::condition_variable post_thread_wait_;
509 std::condition_variable post_thread_ready_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800510
Steven Thomasaf336272018-01-04 17:36:47 -0800511 // When boot is finished this will be set to true and the post thread will be
512 // notified via post_thread_wait_.
513 bool boot_finished_ = false;
514
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800515 // VSync sleep timerfd.
516 pdx::LocalHandle vsync_sleep_timer_fd_;
517
518 // The timestamp of the last vsync.
Corey Tabaka2251d822017-04-20 16:04:07 -0700519 int64_t last_vsync_timestamp_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800520
Corey Tabakab3732f02017-09-16 00:58:54 -0700521 // The number of vsync intervals to predict since the last vsync.
522 int vsync_prediction_interval_ = 1;
523
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800524 // Vsync count since display on.
Corey Tabaka2251d822017-04-20 16:04:07 -0700525 uint32_t vsync_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800526
527 // Counter tracking the number of skipped frames.
Corey Tabaka2251d822017-04-20 16:04:07 -0700528 int frame_skip_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800529
530 // Fd array for tracking retire fences that are returned by hwc. This allows
531 // us to detect when the display driver begins queuing frames.
532 std::vector<pdx::LocalHandle> retire_fence_fds_;
533
Okan Arikan822b7102017-05-08 13:31:34 -0700534 // If we are publishing vsync data, we will put it here.
535 std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800536
John Bates954796e2017-05-11 11:00:31 -0700537 // Broadcast ring for receiving config data from the DisplayManager.
Okan Arikan6f468c62017-05-31 14:48:30 -0700538 DvrConfigRing shared_config_ring_;
John Bates954796e2017-05-11 11:00:31 -0700539 uint32_t shared_config_ring_sequence_{0};
540 // Config buffer for reading from the post thread.
Okan Arikan6f468c62017-05-31 14:48:30 -0700541 DvrConfig post_thread_config_;
John Bates954796e2017-05-11 11:00:31 -0700542 std::mutex shared_config_mutex_;
543
Steven Thomasdfde8fa2018-04-19 16:00:58 -0700544 bool vsync_trace_parity_ = false;
545 sp<VsyncService> vsync_service_;
546
Steven Thomas050b2c82017-03-06 11:45:16 -0800547 static constexpr int kPostThreadInterrupted = 1;
548
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800549 HardwareComposer(const HardwareComposer&) = delete;
550 void operator=(const HardwareComposer&) = delete;
551};
552
553} // namespace dvr
554} // namespace android
555
556#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_