blob: 5a75f423bd74a71f21361afd66ef434a1b3caae1 [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
Corey Tabaka2251d822017-04-20 16:04:07 -07008#include <hardware/gralloc.h>
9#include <log/log.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080010
11#include <array>
12#include <condition_variable>
13#include <memory>
14#include <mutex>
15#include <thread>
16#include <tuple>
17#include <vector>
18
Corey Tabaka2251d822017-04-20 16:04:07 -070019#include <dvr/pose_client.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080020#include <pdx/file_handle.h>
Corey Tabaka2251d822017-04-20 16:04:07 -070021#include <pdx/rpc/variant.h>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080022#include <private/dvr/buffer_hub_client.h>
23#include <private/dvr/frame_time_history.h>
24#include <private/dvr/sync_util.h>
25
26#include "acquired_buffer.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080027#include "display_surface.h"
28
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080029// Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
30#ifndef HWC_TRANSFORM_NONE
31#define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
32#endif
33
34namespace android {
35namespace dvr {
36
37// Basic display metrics for physical displays. Dimensions and densities are
38// relative to the physical display orientation, which may be different from the
39// logical display orientation exposed to applications.
40struct HWCDisplayMetrics {
41 int width;
42 int height;
43 struct {
44 int x;
45 int y;
46 } dpi;
47 int vsync_period_ns;
48};
49
50// Layer represents the connection between a hardware composer layer and the
51// source supplying buffers for the layer's contents.
52class Layer {
53 public:
Corey Tabaka2251d822017-04-20 16:04:07 -070054 Layer() {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080055
Corey Tabaka2251d822017-04-20 16:04:07 -070056 // Sets up the global state used by all Layer instances. This must be called
57 // before using any Layer methods.
58 static void InitializeGlobals(Hwc2::Composer* hwc2_hidl,
59 const HWCDisplayMetrics* metrics);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080060
61 // Releases any shared pointers and fence handles held by this instance.
62 void Reset();
63
64 // Sets up the layer to use a display surface as its content source. The Layer
Corey Tabaka2251d822017-04-20 16:04:07 -070065 // automatically handles ACQUIRE/RELEASE phases for the surface's buffer train
66 // every frame.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080067 //
68 // |blending| receives HWC_BLENDING_* values.
69 // |transform| receives HWC_TRANSFORM_* values.
70 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
71 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Corey Tabaka2251d822017-04-20 16:04:07 -070072 // |index| is the index of this surface in the DirectDisplaySurface array.
73 void Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
74 HWC::BlendMode blending, HWC::Transform transform,
75 HWC::Composition composition_type, size_t z_roder);
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 //
81 // |blending| receives HWC_BLENDING_* values.
82 // |transform| receives HWC_TRANSFORM_* values.
83 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
84 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Corey Tabaka2251d822017-04-20 16:04:07 -070085 void Setup(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
86 HWC::Transform transform, HWC::Composition composition_type,
87 size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080088
89 // Layers that use a direct IonBuffer should call this each frame to update
90 // which buffer will be used for the next PostLayers.
Corey Tabaka2251d822017-04-20 16:04:07 -070091 void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080092
93 // Sets up the hardware composer layer for the next frame. When the layer is
94 // associated with a display surface, this method automatically ACQUIRES a new
95 // buffer if one is available.
96 void Prepare();
97
98 // After calling prepare, if this frame is to be dropped instead of passing
99 // along to the HWC, call Drop to close the contained fence(s).
100 void Drop();
101
102 // Performs fence bookkeeping after the frame has been posted to hardware
103 // composer.
104 void Finish(int release_fence_fd);
105
106 // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
Corey Tabaka2251d822017-04-20 16:04:07 -0700107 void SetBlending(HWC::BlendMode blending);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800108
Corey Tabaka2251d822017-04-20 16:04:07 -0700109 // Sets the z-order of this layer
110 void SetZOrder(size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800111
112 // Gets the current IonBuffer associated with this layer. Ownership of the
113 // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
114 // remain valid across calls to Layer::Setup(), Layer::Prepare(), or
115 // Layer::Reset(). YOU HAVE BEEN WARNED.
116 IonBuffer* GetBuffer();
117
Corey Tabaka2251d822017-04-20 16:04:07 -0700118 HWC::Composition GetCompositionType() const { return composition_type_; }
119 HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
120 bool IsLayerSetup() const { return !source_.empty(); }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800121
122 // Applies all of the settings to this layer using the hwc functions
123 void UpdateLayerSettings();
124
125 int GetSurfaceId() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700126 int surface_id = -1;
127 pdx::rpc::IfAnyOf<SourceSurface>::Call(
128 &source_, [&surface_id](const SourceSurface& surface_source) {
129 surface_id = surface_source.surface->surface_id();
130 });
131 return surface_id;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800132 }
133
134 private:
135 void CommonLayerSetup();
136
Corey Tabaka2251d822017-04-20 16:04:07 -0700137 static Hwc2::Composer* hwc2_hidl_;
138 static const HWCDisplayMetrics* display_metrics_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800139
140 // The hardware composer layer and metrics to use during the prepare cycle.
Corey Tabaka2251d822017-04-20 16:04:07 -0700141 hwc2_layer_t hardware_composer_layer_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800142
143 // Layer properties used to setup the hardware composer layer during the
144 // Prepare phase.
Corey Tabaka2251d822017-04-20 16:04:07 -0700145 size_t z_order_ = 0;
146 HWC::BlendMode blending_ = HWC::BlendMode::None;
147 HWC::Transform transform_ = HWC::Transform::None;
148 HWC::Composition composition_type_ = HWC::Composition::Invalid;
149 HWC::Composition target_composition_type_ = HWC::Composition::Device;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800150
Corey Tabaka2251d822017-04-20 16:04:07 -0700151 // State when the layer is connected to a surface. Provides the same interface
152 // as SourceBuffer to simplify internal use by Layer.
153 struct SourceSurface {
154 std::shared_ptr<DirectDisplaySurface> surface;
155 AcquiredBuffer acquired_buffer;
156 pdx::LocalHandle release_fence;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800157
Corey Tabaka2251d822017-04-20 16:04:07 -0700158 SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
159 : surface(surface) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800160
Corey Tabaka2251d822017-04-20 16:04:07 -0700161 // Attempts to acquire a new buffer from the surface and return a tuple with
162 // width, height, buffer handle, and fence. If a new buffer is not available
163 // the previous buffer is returned or an empty value if no buffer has ever
164 // been posted. When a new buffer is acquired the previous buffer's release
165 // fence is passed out automatically.
166 std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
167 if (surface->IsBufferAvailable()) {
168 acquired_buffer.Release(std::move(release_fence));
169 acquired_buffer = surface->AcquireCurrentBuffer();
170 ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
171 }
172 if (!acquired_buffer.IsEmpty()) {
173 return std::make_tuple(acquired_buffer.buffer()->width(),
174 acquired_buffer.buffer()->height(),
175 acquired_buffer.buffer()->buffer()->buffer(),
176 acquired_buffer.ClaimAcquireFence());
177 } else {
178 return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
179 }
180 }
181
182 void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
183
184 // Gets a pointer to the current acquired buffer or returns nullptr if there
185 // isn't one.
186 IonBuffer* GetBuffer() {
187 if (acquired_buffer.IsAvailable())
188 return acquired_buffer.buffer()->buffer();
189 else
190 return nullptr;
191 }
192
193 // Returns the surface id of the surface.
194 int GetSurfaceId() { return surface->surface_id(); }
195 };
196
197 // State when the layer is connected to a buffer. Provides the same interface
198 // as SourceSurface to simplify internal use by Layer.
199 struct SourceBuffer {
200 std::shared_ptr<IonBuffer> buffer;
201
202 std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
203 if (buffer)
204 return std::make_tuple(buffer->width(), buffer->height(),
205 buffer->buffer(), pdx::LocalHandle{});
206 else
207 return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
208 }
209
210 void Finish(pdx::LocalHandle /*fence*/) {}
211
212 IonBuffer* GetBuffer() { return buffer.get(); }
213
214 int GetSurfaceId() const { return -1; }
215 };
216
217 // The underlying hardware composer layer is supplied buffers either from a
218 // surface buffer train or from a buffer directly.
219 pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
220
221 pdx::LocalHandle acquire_fence_;
222 bool surface_rect_functions_applied_ = false;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800223
224 Layer(const Layer&) = delete;
225 void operator=(const Layer&) = delete;
226};
227
228// HardwareComposer encapsulates the hardware composer HAL, exposing a
229// simplified API to post buffers to the display.
Steven Thomas050b2c82017-03-06 11:45:16 -0800230//
231// HardwareComposer is accessed by both the vr flinger dispatcher thread and the
232// surface flinger main thread, in addition to internally running a separate
233// thread for compositing/EDS and posting layers to the HAL. When changing how
234// variables are used or adding new state think carefully about which threads
235// will access the state and whether it needs to be synchronized.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800236class HardwareComposer {
237 public:
238 // Type for vsync callback.
239 using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
Corey Tabaka2251d822017-04-20 16:04:07 -0700240 using RequestDisplayCallback = std::function<void(bool)>;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800241
242 // Since there is no universal way to query the number of hardware layers,
243 // just set it to 4 for now.
Corey Tabaka2251d822017-04-20 16:04:07 -0700244 static constexpr size_t kMaxHardwareLayers = 4;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800245
246 HardwareComposer();
Corey Tabaka2251d822017-04-20 16:04:07 -0700247 HardwareComposer(Hwc2::Composer* hidl,
248 RequestDisplayCallback request_display_callback);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800249 ~HardwareComposer();
250
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800251 bool Initialize();
252
253 bool IsInitialized() const { return initialized_; }
254
Steven Thomas050b2c82017-03-06 11:45:16 -0800255 // Start the post thread if there's work to do (i.e. visible layers). This
256 // should only be called from surface flinger's main thread.
257 void Enable();
258 // Pause the post thread, blocking until the post thread has signaled that
259 // it's paused. This should only be called from surface flinger's main thread.
260 void Disable();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800261
262 // Get the HMD display metrics for the current display.
Corey Tabaka2251d822017-04-20 16:04:07 -0700263 display::Metrics GetHmdDisplayMetrics() const;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800264
Corey Tabaka2251d822017-04-20 16:04:07 -0700265 HWC::Error GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
266 hwc2_attribute_t attributes,
267 int32_t* out_value) const;
268 HWC::Error GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config,
269 HWCDisplayMetrics* out_metrics) const;
270 std::string Dump();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800271
272 void SetVSyncCallback(VSyncCallback callback);
273
274 // Metrics of the logical display, which is always landscape.
275 int DisplayWidth() const { return display_metrics_.width; }
276 int DisplayHeight() const { return display_metrics_.height; }
277 HWCDisplayMetrics display_metrics() const { return display_metrics_; }
278
279 // Metrics of the native display, which depends on the specific hardware
280 // implementation of the display.
281 HWCDisplayMetrics native_display_metrics() const {
282 return native_display_metrics_;
283 }
284
Corey Tabaka2251d822017-04-20 16:04:07 -0700285 // Sets the display surfaces to compose the hardware layer stack.
Steven Thomas050b2c82017-03-06 11:45:16 -0800286 void SetDisplaySurfaces(
Corey Tabaka2251d822017-04-20 16:04:07 -0700287 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800288
Steven Thomas3cfac282017-02-06 12:29:30 -0800289 void OnHardwareComposerRefresh();
290
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800291 private:
292 int32_t EnableVsync(bool enabled);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800293
294 class ComposerCallback : public Hwc2::IComposerCallback {
295 public:
296 ComposerCallback() {}
297
298 hardware::Return<void> onHotplug(Hwc2::Display /*display*/,
299 Connection /*connected*/) override {
300 // TODO(skiazyk): depending on how the server is implemented, we might
301 // have to set it up to synchronize with receiving this event, as it can
302 // potentially be a critical event for setting up state within the
303 // hwc2 module. That is, we (technically) should not call any other hwc
304 // methods until this method has been called after registering the
305 // callbacks.
306 return hardware::Void();
307 }
308
309 hardware::Return<void> onRefresh(Hwc2::Display /*display*/) override {
310 return hardware::Void();
311 }
312
313 hardware::Return<void> onVsync(Hwc2::Display /*display*/,
314 int64_t /*timestamp*/) override {
315 return hardware::Void();
316 }
317 };
318
Corey Tabaka2251d822017-04-20 16:04:07 -0700319 HWC::Error Validate(hwc2_display_t display);
320 HWC::Error Present(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800321
322 void SetBacklightBrightness(int brightness);
323
Corey Tabaka2251d822017-04-20 16:04:07 -0700324 void PostLayers();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800325 void PostThread();
326
Corey Tabaka2251d822017-04-20 16:04:07 -0700327 // The post thread has two controlling states:
328 // 1. Idle: no work to do (no visible surfaces).
329 // 2. Suspended: explicitly halted (system is not in VR mode).
330 // When either #1 or #2 is true then the post thread is quiescent, otherwise
331 // it is active.
332 using PostThreadStateType = uint32_t;
333 struct PostThreadState {
334 enum : PostThreadStateType {
335 Active = 0,
336 Idle = (1 << 0),
337 Suspended = (1 << 1),
338 Quit = (1 << 2),
339 };
340 };
341
342 void UpdatePostThreadState(uint32_t state, bool suspend);
343
Steven Thomas050b2c82017-03-06 11:45:16 -0800344 // Blocks until either event_fd becomes readable, or we're interrupted by a
345 // control thread. Any errors are returned as negative errno values. If we're
346 // interrupted, kPostThreadInterrupted will be returned.
Corey Tabaka2251d822017-04-20 16:04:07 -0700347 int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
348 int requested_events);
Steven Thomas050b2c82017-03-06 11:45:16 -0800349
350 // BlockUntilVSync, WaitForVSync, and SleepUntil are all blocking calls made
351 // on the post thread that can be interrupted by a control thread. If
352 // interrupted, these calls return kPostThreadInterrupted.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800353 int ReadWaitPPState();
Steven Thomas050b2c82017-03-06 11:45:16 -0800354 int BlockUntilVSync();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800355 int ReadVSyncTimestamp(int64_t* timestamp);
356 int WaitForVSync(int64_t* timestamp);
357 int SleepUntil(int64_t wakeup_timestamp);
358
359 bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; }
360
Corey Tabaka2251d822017-04-20 16:04:07 -0700361 // Reconfigures the layer stack if the display surfaces changed since the last
362 // frame. Called only from the post thread.
Steven Thomas050b2c82017-03-06 11:45:16 -0800363 bool UpdateLayerConfig();
Steven Thomas050b2c82017-03-06 11:45:16 -0800364
365 // Called on the post thread when the post thread is resumed.
366 void OnPostThreadResumed();
367 // Called on the post thread when the post thread is paused or quits.
368 void OnPostThreadPaused();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800369
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800370 bool initialized_;
371
Corey Tabaka2251d822017-04-20 16:04:07 -0700372 // Hardware composer HAL device from SurfaceFlinger. VrFlinger does not own
373 // this pointer.
374 Hwc2::Composer* hwc2_hidl_;
375 RequestDisplayCallback request_display_callback_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800376 sp<ComposerCallback> callbacks_;
377
378 // Display metrics of the physical display.
379 HWCDisplayMetrics native_display_metrics_;
380 // Display metrics of the logical display, adjusted so that orientation is
381 // landscape.
382 HWCDisplayMetrics display_metrics_;
383 // Transform required to get from native to logical display orientation.
Corey Tabaka2251d822017-04-20 16:04:07 -0700384 HWC::Transform display_transform_ = HWC::Transform::None;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800385
386 // Buffer for the background layer required by hardware composer.
387 std::shared_ptr<IonBuffer> framebuffer_target_;
388
Corey Tabaka2251d822017-04-20 16:04:07 -0700389 // Pending surface list. Set by the display service when DirectSurfaces are
390 // added, removed, or change visibility. Written by the message dispatch
391 // thread and read by the post thread.
392 std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800393
394 // The surfaces displayed by the post thread. Used exclusively by the post
395 // thread.
Corey Tabaka2251d822017-04-20 16:04:07 -0700396 std::vector<std::shared_ptr<DirectDisplaySurface>> display_surfaces_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800397
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800398 // Layer array for handling buffer flow into hardware composer layers.
Corey Tabaka2251d822017-04-20 16:04:07 -0700399 std::array<Layer, kMaxHardwareLayers> layers_;
400 size_t active_layer_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800401
402 // Handler to hook vsync events outside of this class.
403 VSyncCallback vsync_callback_;
404
Steven Thomas282a5ed2017-02-07 18:07:01 -0800405 // The layer posting thread. This thread wakes up a short time before vsync to
Corey Tabaka2251d822017-04-20 16:04:07 -0700406 // hand buffers to hardware composer.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800407 std::thread post_thread_;
408
Corey Tabaka2251d822017-04-20 16:04:07 -0700409 // Post thread state machine and synchronization primitives.
410 PostThreadStateType post_thread_state_{PostThreadState::Idle};
411 std::atomic<bool> post_thread_quiescent_{true};
412 bool post_thread_resumed_{false};
413 pdx::LocalHandle post_thread_event_fd_;
414 std::mutex post_thread_mutex_;
415 std::condition_variable post_thread_wait_;
416 std::condition_variable post_thread_ready_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800417
418 // Backlight LED brightness sysfs node.
419 pdx::LocalHandle backlight_brightness_fd_;
420
421 // Primary display vsync event sysfs node.
422 pdx::LocalHandle primary_display_vsync_event_fd_;
423
424 // Primary display wait_pingpong state sysfs node.
425 pdx::LocalHandle primary_display_wait_pp_fd_;
426
427 // VSync sleep timerfd.
428 pdx::LocalHandle vsync_sleep_timer_fd_;
429
430 // The timestamp of the last vsync.
Corey Tabaka2251d822017-04-20 16:04:07 -0700431 int64_t last_vsync_timestamp_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800432
433 // Vsync count since display on.
Corey Tabaka2251d822017-04-20 16:04:07 -0700434 uint32_t vsync_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800435
436 // Counter tracking the number of skipped frames.
Corey Tabaka2251d822017-04-20 16:04:07 -0700437 int frame_skip_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800438
439 // Fd array for tracking retire fences that are returned by hwc. This allows
440 // us to detect when the display driver begins queuing frames.
441 std::vector<pdx::LocalHandle> retire_fence_fds_;
442
443 // Pose client for frame count notifications. Pose client predicts poses
444 // out to display frame boundaries, so we need to tell it about vsyncs.
Corey Tabaka2251d822017-04-20 16:04:07 -0700445 DvrPose* pose_client_ = nullptr;
Steven Thomas050b2c82017-03-06 11:45:16 -0800446
447 static constexpr int kPostThreadInterrupted = 1;
448
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800449 static void HwcRefresh(hwc2_callback_data_t data, hwc2_display_t display);
450 static void HwcVSync(hwc2_callback_data_t data, hwc2_display_t display,
451 int64_t timestamp);
452 static void HwcHotplug(hwc2_callback_data_t callbackData,
453 hwc2_display_t display, hwc2_connection_t connected);
454
455 HardwareComposer(const HardwareComposer&) = delete;
456 void operator=(const HardwareComposer&) = delete;
457};
458
459} // namespace dvr
460} // namespace android
461
462#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_