blob: 8ba72ab7739dcfd76ace188c898f6c8131a29dc6 [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>
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080023
24#include "acquired_buffer.h"
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080025#include "display_surface.h"
26
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080027// Hardware composer HAL doesn't define HWC_TRANSFORM_NONE as of this writing.
28#ifndef HWC_TRANSFORM_NONE
29#define HWC_TRANSFORM_NONE static_cast<hwc_transform_t>(0)
30#endif
31
32namespace android {
33namespace dvr {
34
35// Basic display metrics for physical displays. Dimensions and densities are
36// relative to the physical display orientation, which may be different from the
37// logical display orientation exposed to applications.
38struct HWCDisplayMetrics {
39 int width;
40 int height;
41 struct {
42 int x;
43 int y;
44 } dpi;
45 int vsync_period_ns;
46};
47
48// Layer represents the connection between a hardware composer layer and the
49// source supplying buffers for the layer's contents.
50class Layer {
51 public:
Corey Tabaka2251d822017-04-20 16:04:07 -070052 Layer() {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080053
Corey Tabaka2251d822017-04-20 16:04:07 -070054 // Sets up the global state used by all Layer instances. This must be called
55 // before using any Layer methods.
56 static void InitializeGlobals(Hwc2::Composer* hwc2_hidl,
57 const HWCDisplayMetrics* metrics);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080058
59 // Releases any shared pointers and fence handles held by this instance.
60 void Reset();
61
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 //
66 // |blending| receives HWC_BLENDING_* values.
67 // |transform| receives HWC_TRANSFORM_* values.
68 // |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.
71 void Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
72 HWC::BlendMode blending, HWC::Transform transform,
73 HWC::Composition composition_type, size_t z_roder);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080074
75 // Sets up the layer to use a direct buffer as its content source. No special
76 // handling of the buffer is performed; responsibility for updating or
77 // changing the buffer each frame is on the caller.
78 //
79 // |blending| receives HWC_BLENDING_* values.
80 // |transform| receives HWC_TRANSFORM_* values.
81 // |composition_type| receives either HWC_FRAMEBUFFER for most layers or
82 // HWC_FRAMEBUFFER_TARGET (unless you know what you are doing).
Corey Tabaka2251d822017-04-20 16:04:07 -070083 void Setup(const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
84 HWC::Transform transform, HWC::Composition composition_type,
85 size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080086
87 // Layers that use a direct IonBuffer should call this each frame to update
88 // which buffer will be used for the next PostLayers.
Corey Tabaka2251d822017-04-20 16:04:07 -070089 void UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080090
91 // Sets up the hardware composer layer for the next frame. When the layer is
92 // associated with a display surface, this method automatically ACQUIRES a new
93 // buffer if one is available.
94 void Prepare();
95
96 // After calling prepare, if this frame is to be dropped instead of passing
97 // along to the HWC, call Drop to close the contained fence(s).
98 void Drop();
99
100 // Performs fence bookkeeping after the frame has been posted to hardware
101 // composer.
102 void Finish(int release_fence_fd);
103
104 // Sets the blending for the layer. |blending| receives HWC_BLENDING_* values.
Corey Tabaka2251d822017-04-20 16:04:07 -0700105 void SetBlending(HWC::BlendMode blending);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800106
Corey Tabaka2251d822017-04-20 16:04:07 -0700107 // Sets the z-order of this layer
108 void SetZOrder(size_t z_order);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800109
110 // Gets the current IonBuffer associated with this layer. Ownership of the
111 // buffer DOES NOT pass to the caller and the pointer is not guaranteed to
112 // remain valid across calls to Layer::Setup(), Layer::Prepare(), or
113 // Layer::Reset(). YOU HAVE BEEN WARNED.
114 IonBuffer* GetBuffer();
115
Corey Tabaka2251d822017-04-20 16:04:07 -0700116 HWC::Composition GetCompositionType() const { return composition_type_; }
117 HWC::Layer GetLayerHandle() const { return hardware_composer_layer_; }
118 bool IsLayerSetup() const { return !source_.empty(); }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800119
120 // Applies all of the settings to this layer using the hwc functions
121 void UpdateLayerSettings();
122
123 int GetSurfaceId() const {
Corey Tabaka2251d822017-04-20 16:04:07 -0700124 int surface_id = -1;
125 pdx::rpc::IfAnyOf<SourceSurface>::Call(
126 &source_, [&surface_id](const SourceSurface& surface_source) {
127 surface_id = surface_source.surface->surface_id();
128 });
129 return surface_id;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800130 }
131
132 private:
133 void CommonLayerSetup();
134
Corey Tabaka2251d822017-04-20 16:04:07 -0700135 static Hwc2::Composer* hwc2_hidl_;
136 static const HWCDisplayMetrics* display_metrics_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800137
138 // The hardware composer layer and metrics to use during the prepare cycle.
Corey Tabaka2251d822017-04-20 16:04:07 -0700139 hwc2_layer_t hardware_composer_layer_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800140
141 // Layer properties used to setup the hardware composer layer during the
142 // Prepare phase.
Corey Tabaka2251d822017-04-20 16:04:07 -0700143 size_t z_order_ = 0;
144 HWC::BlendMode blending_ = HWC::BlendMode::None;
145 HWC::Transform transform_ = HWC::Transform::None;
146 HWC::Composition composition_type_ = HWC::Composition::Invalid;
147 HWC::Composition target_composition_type_ = HWC::Composition::Device;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800148
Corey Tabaka2251d822017-04-20 16:04:07 -0700149 // State when the layer is connected to a surface. Provides the same interface
150 // as SourceBuffer to simplify internal use by Layer.
151 struct SourceSurface {
152 std::shared_ptr<DirectDisplaySurface> surface;
153 AcquiredBuffer acquired_buffer;
154 pdx::LocalHandle release_fence;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800155
Corey Tabaka2251d822017-04-20 16:04:07 -0700156 SourceSurface(const std::shared_ptr<DirectDisplaySurface>& surface)
157 : surface(surface) {}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800158
Corey Tabaka2251d822017-04-20 16:04:07 -0700159 // Attempts to acquire a new buffer from the surface and return a tuple with
160 // width, height, buffer handle, and fence. If a new buffer is not available
161 // the previous buffer is returned or an empty value if no buffer has ever
162 // been posted. When a new buffer is acquired the previous buffer's release
163 // fence is passed out automatically.
164 std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
165 if (surface->IsBufferAvailable()) {
166 acquired_buffer.Release(std::move(release_fence));
167 acquired_buffer = surface->AcquireCurrentBuffer();
168 ATRACE_ASYNC_END("BufferPost", acquired_buffer.buffer()->id());
169 }
170 if (!acquired_buffer.IsEmpty()) {
171 return std::make_tuple(acquired_buffer.buffer()->width(),
172 acquired_buffer.buffer()->height(),
173 acquired_buffer.buffer()->buffer()->buffer(),
174 acquired_buffer.ClaimAcquireFence());
175 } else {
176 return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
177 }
178 }
179
180 void Finish(pdx::LocalHandle fence) { release_fence = std::move(fence); }
181
182 // Gets a pointer to the current acquired buffer or returns nullptr if there
183 // isn't one.
184 IonBuffer* GetBuffer() {
185 if (acquired_buffer.IsAvailable())
186 return acquired_buffer.buffer()->buffer();
187 else
188 return nullptr;
189 }
190
191 // Returns the surface id of the surface.
192 int GetSurfaceId() { return surface->surface_id(); }
193 };
194
195 // State when the layer is connected to a buffer. Provides the same interface
196 // as SourceSurface to simplify internal use by Layer.
197 struct SourceBuffer {
198 std::shared_ptr<IonBuffer> buffer;
199
200 std::tuple<int, int, sp<GraphicBuffer>, pdx::LocalHandle> Acquire() {
201 if (buffer)
202 return std::make_tuple(buffer->width(), buffer->height(),
203 buffer->buffer(), pdx::LocalHandle{});
204 else
205 return std::make_tuple(0, 0, nullptr, pdx::LocalHandle{});
206 }
207
208 void Finish(pdx::LocalHandle /*fence*/) {}
209
210 IonBuffer* GetBuffer() { return buffer.get(); }
211
212 int GetSurfaceId() const { return -1; }
213 };
214
215 // The underlying hardware composer layer is supplied buffers either from a
216 // surface buffer train or from a buffer directly.
217 pdx::rpc::Variant<SourceSurface, SourceBuffer> source_;
218
219 pdx::LocalHandle acquire_fence_;
220 bool surface_rect_functions_applied_ = false;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800221
222 Layer(const Layer&) = delete;
223 void operator=(const Layer&) = delete;
224};
225
226// HardwareComposer encapsulates the hardware composer HAL, exposing a
227// simplified API to post buffers to the display.
Steven Thomas050b2c82017-03-06 11:45:16 -0800228//
229// HardwareComposer is accessed by both the vr flinger dispatcher thread and the
230// surface flinger main thread, in addition to internally running a separate
231// thread for compositing/EDS and posting layers to the HAL. When changing how
232// variables are used or adding new state think carefully about which threads
233// will access the state and whether it needs to be synchronized.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800234class HardwareComposer {
235 public:
236 // Type for vsync callback.
237 using VSyncCallback = std::function<void(int, int64_t, int64_t, uint32_t)>;
Corey Tabaka2251d822017-04-20 16:04:07 -0700238 using RequestDisplayCallback = std::function<void(bool)>;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800239
240 // Since there is no universal way to query the number of hardware layers,
241 // just set it to 4 for now.
Corey Tabaka2251d822017-04-20 16:04:07 -0700242 static constexpr size_t kMaxHardwareLayers = 4;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800243
244 HardwareComposer();
Corey Tabaka2251d822017-04-20 16:04:07 -0700245 HardwareComposer(Hwc2::Composer* hidl,
246 RequestDisplayCallback request_display_callback);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800247 ~HardwareComposer();
248
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800249 bool Initialize();
250
251 bool IsInitialized() const { return initialized_; }
252
Steven Thomas050b2c82017-03-06 11:45:16 -0800253 // Start the post thread if there's work to do (i.e. visible layers). This
254 // should only be called from surface flinger's main thread.
255 void Enable();
256 // Pause the post thread, blocking until the post thread has signaled that
257 // it's paused. This should only be called from surface flinger's main thread.
258 void Disable();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800259
260 // Get the HMD display metrics for the current display.
Corey Tabaka2251d822017-04-20 16:04:07 -0700261 display::Metrics GetHmdDisplayMetrics() const;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800262
Corey Tabaka2251d822017-04-20 16:04:07 -0700263 HWC::Error GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
264 hwc2_attribute_t attributes,
265 int32_t* out_value) const;
266 HWC::Error GetDisplayMetrics(hwc2_display_t display, hwc2_config_t config,
267 HWCDisplayMetrics* out_metrics) const;
268 std::string Dump();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800269
270 void SetVSyncCallback(VSyncCallback callback);
271
272 // Metrics of the logical display, which is always landscape.
273 int DisplayWidth() const { return display_metrics_.width; }
274 int DisplayHeight() const { return display_metrics_.height; }
275 HWCDisplayMetrics display_metrics() const { return display_metrics_; }
276
277 // Metrics of the native display, which depends on the specific hardware
278 // implementation of the display.
279 HWCDisplayMetrics native_display_metrics() const {
280 return native_display_metrics_;
281 }
282
Corey Tabaka2251d822017-04-20 16:04:07 -0700283 // Sets the display surfaces to compose the hardware layer stack.
Steven Thomas050b2c82017-03-06 11:45:16 -0800284 void SetDisplaySurfaces(
Corey Tabaka2251d822017-04-20 16:04:07 -0700285 std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800286
Steven Thomas3cfac282017-02-06 12:29:30 -0800287 void OnHardwareComposerRefresh();
288
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800289 private:
290 int32_t EnableVsync(bool enabled);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800291
292 class ComposerCallback : public Hwc2::IComposerCallback {
293 public:
294 ComposerCallback() {}
295
296 hardware::Return<void> onHotplug(Hwc2::Display /*display*/,
297 Connection /*connected*/) override {
298 // TODO(skiazyk): depending on how the server is implemented, we might
299 // have to set it up to synchronize with receiving this event, as it can
300 // potentially be a critical event for setting up state within the
301 // hwc2 module. That is, we (technically) should not call any other hwc
302 // methods until this method has been called after registering the
303 // callbacks.
304 return hardware::Void();
305 }
306
307 hardware::Return<void> onRefresh(Hwc2::Display /*display*/) override {
308 return hardware::Void();
309 }
310
311 hardware::Return<void> onVsync(Hwc2::Display /*display*/,
312 int64_t /*timestamp*/) override {
313 return hardware::Void();
314 }
315 };
316
Corey Tabaka2251d822017-04-20 16:04:07 -0700317 HWC::Error Validate(hwc2_display_t display);
318 HWC::Error Present(hwc2_display_t display);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800319
320 void SetBacklightBrightness(int brightness);
321
Corey Tabaka2251d822017-04-20 16:04:07 -0700322 void PostLayers();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800323 void PostThread();
324
Corey Tabaka2251d822017-04-20 16:04:07 -0700325 // The post thread has two controlling states:
326 // 1. Idle: no work to do (no visible surfaces).
327 // 2. Suspended: explicitly halted (system is not in VR mode).
328 // When either #1 or #2 is true then the post thread is quiescent, otherwise
329 // it is active.
330 using PostThreadStateType = uint32_t;
331 struct PostThreadState {
332 enum : PostThreadStateType {
333 Active = 0,
334 Idle = (1 << 0),
335 Suspended = (1 << 1),
336 Quit = (1 << 2),
337 };
338 };
339
340 void UpdatePostThreadState(uint32_t state, bool suspend);
341
Steven Thomas050b2c82017-03-06 11:45:16 -0800342 // Blocks until either event_fd becomes readable, or we're interrupted by a
343 // control thread. Any errors are returned as negative errno values. If we're
344 // interrupted, kPostThreadInterrupted will be returned.
Corey Tabaka2251d822017-04-20 16:04:07 -0700345 int PostThreadPollInterruptible(const pdx::LocalHandle& event_fd,
346 int requested_events);
Steven Thomas050b2c82017-03-06 11:45:16 -0800347
348 // BlockUntilVSync, WaitForVSync, and SleepUntil are all blocking calls made
349 // on the post thread that can be interrupted by a control thread. If
350 // interrupted, these calls return kPostThreadInterrupted.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800351 int ReadWaitPPState();
Steven Thomas050b2c82017-03-06 11:45:16 -0800352 int BlockUntilVSync();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800353 int ReadVSyncTimestamp(int64_t* timestamp);
354 int WaitForVSync(int64_t* timestamp);
355 int SleepUntil(int64_t wakeup_timestamp);
356
357 bool IsFramePendingInDriver() { return ReadWaitPPState() == 1; }
358
Corey Tabaka2251d822017-04-20 16:04:07 -0700359 // Reconfigures the layer stack if the display surfaces changed since the last
360 // frame. Called only from the post thread.
Steven Thomas050b2c82017-03-06 11:45:16 -0800361 bool UpdateLayerConfig();
Steven Thomas050b2c82017-03-06 11:45:16 -0800362
363 // Called on the post thread when the post thread is resumed.
364 void OnPostThreadResumed();
365 // Called on the post thread when the post thread is paused or quits.
366 void OnPostThreadPaused();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800367
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800368 bool initialized_;
369
Corey Tabaka2251d822017-04-20 16:04:07 -0700370 // Hardware composer HAL device from SurfaceFlinger. VrFlinger does not own
371 // this pointer.
372 Hwc2::Composer* hwc2_hidl_;
373 RequestDisplayCallback request_display_callback_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800374 sp<ComposerCallback> callbacks_;
375
376 // Display metrics of the physical display.
377 HWCDisplayMetrics native_display_metrics_;
378 // Display metrics of the logical display, adjusted so that orientation is
379 // landscape.
380 HWCDisplayMetrics display_metrics_;
381 // Transform required to get from native to logical display orientation.
Corey Tabaka2251d822017-04-20 16:04:07 -0700382 HWC::Transform display_transform_ = HWC::Transform::None;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800383
Corey Tabaka2251d822017-04-20 16:04:07 -0700384 // Pending surface list. Set by the display service when DirectSurfaces are
385 // added, removed, or change visibility. Written by the message dispatch
386 // thread and read by the post thread.
387 std::vector<std::shared_ptr<DirectDisplaySurface>> pending_surfaces_;
Steven Thomas050b2c82017-03-06 11:45:16 -0800388
389 // The surfaces displayed by the post thread. Used exclusively by the post
390 // thread.
Corey Tabaka2251d822017-04-20 16:04:07 -0700391 std::vector<std::shared_ptr<DirectDisplaySurface>> display_surfaces_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800392
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800393 // Layer array for handling buffer flow into hardware composer layers.
Corey Tabaka2251d822017-04-20 16:04:07 -0700394 std::array<Layer, kMaxHardwareLayers> layers_;
395 size_t active_layer_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800396
397 // Handler to hook vsync events outside of this class.
398 VSyncCallback vsync_callback_;
399
Steven Thomas282a5ed2017-02-07 18:07:01 -0800400 // The layer posting thread. This thread wakes up a short time before vsync to
Corey Tabaka2251d822017-04-20 16:04:07 -0700401 // hand buffers to hardware composer.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800402 std::thread post_thread_;
403
Corey Tabaka2251d822017-04-20 16:04:07 -0700404 // Post thread state machine and synchronization primitives.
405 PostThreadStateType post_thread_state_{PostThreadState::Idle};
406 std::atomic<bool> post_thread_quiescent_{true};
407 bool post_thread_resumed_{false};
408 pdx::LocalHandle post_thread_event_fd_;
409 std::mutex post_thread_mutex_;
410 std::condition_variable post_thread_wait_;
411 std::condition_variable post_thread_ready_;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800412
413 // Backlight LED brightness sysfs node.
414 pdx::LocalHandle backlight_brightness_fd_;
415
416 // Primary display vsync event sysfs node.
417 pdx::LocalHandle primary_display_vsync_event_fd_;
418
419 // Primary display wait_pingpong state sysfs node.
420 pdx::LocalHandle primary_display_wait_pp_fd_;
421
422 // VSync sleep timerfd.
423 pdx::LocalHandle vsync_sleep_timer_fd_;
424
425 // The timestamp of the last vsync.
Corey Tabaka2251d822017-04-20 16:04:07 -0700426 int64_t last_vsync_timestamp_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800427
428 // Vsync count since display on.
Corey Tabaka2251d822017-04-20 16:04:07 -0700429 uint32_t vsync_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800430
431 // Counter tracking the number of skipped frames.
Corey Tabaka2251d822017-04-20 16:04:07 -0700432 int frame_skip_count_ = 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800433
434 // Fd array for tracking retire fences that are returned by hwc. This allows
435 // us to detect when the display driver begins queuing frames.
436 std::vector<pdx::LocalHandle> retire_fence_fds_;
437
438 // Pose client for frame count notifications. Pose client predicts poses
439 // out to display frame boundaries, so we need to tell it about vsyncs.
Corey Tabaka2251d822017-04-20 16:04:07 -0700440 DvrPose* pose_client_ = nullptr;
Steven Thomas050b2c82017-03-06 11:45:16 -0800441
442 static constexpr int kPostThreadInterrupted = 1;
443
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800444 static void HwcRefresh(hwc2_callback_data_t data, hwc2_display_t display);
445 static void HwcVSync(hwc2_callback_data_t data, hwc2_display_t display,
446 int64_t timestamp);
447 static void HwcHotplug(hwc2_callback_data_t callbackData,
448 hwc2_display_t display, hwc2_connection_t connected);
449
450 HardwareComposer(const HardwareComposer&) = delete;
451 void operator=(const HardwareComposer&) = delete;
452};
453
454} // namespace dvr
455} // namespace android
456
457#endif // ANDROID_DVR_SERVICES_DISPLAYD_HARDWARE_COMPOSER_H_