OSDN Git Service

Merge "Fix race condition clearing VSYNC enable on VrFlinger startup." into oc-dr1-dev
[android-x86/frameworks-native.git] / libs / vr / libvrflinger / hardware_composer.cpp
1 #include "hardware_composer.h"
2
3 #include <cutils/properties.h>
4 #include <cutils/sched_policy.h>
5 #include <fcntl.h>
6 #include <log/log.h>
7 #include <poll.h>
8 #include <sync/sync.h>
9 #include <sys/eventfd.h>
10 #include <sys/prctl.h>
11 #include <sys/resource.h>
12 #include <sys/system_properties.h>
13 #include <sys/timerfd.h>
14 #include <time.h>
15 #include <unistd.h>
16 #include <utils/Trace.h>
17
18 #include <algorithm>
19 #include <chrono>
20 #include <functional>
21 #include <map>
22 #include <sstream>
23 #include <string>
24 #include <tuple>
25
26 #include <dvr/dvr_display_types.h>
27 #include <dvr/performance_client_api.h>
28 #include <private/dvr/clock_ns.h>
29 #include <private/dvr/ion_buffer.h>
30
31 using android::pdx::LocalHandle;
32 using android::pdx::rpc::EmptyVariant;
33 using android::pdx::rpc::IfAnyOf;
34
35 using namespace std::chrono_literals;
36
37 namespace android {
38 namespace dvr {
39
40 namespace {
41
42 const char kBacklightBrightnessSysFile[] =
43     "/sys/class/leds/lcd-backlight/brightness";
44
45 const char kPrimaryDisplayVSyncEventFile[] =
46     "/sys/class/graphics/fb0/vsync_event";
47
48 const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";
49
50 const char kDvrPerformanceProperty[] = "sys.dvr.performance";
51
52 const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";
53
54 // Get time offset from a vsync to when the pose for that vsync should be
55 // predicted out to. For example, if scanout gets halfway through the frame
56 // at the halfway point between vsyncs, then this could be half the period.
57 // With global shutter displays, this should be changed to the offset to when
58 // illumination begins. Low persistence adds a frame of latency, so we predict
59 // to the center of the next frame.
60 inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
61   return (vsync_period_ns * 150) / 100;
62 }
63
64 // Attempts to set the scheduler class and partiton for the current thread.
65 // Returns true on success or false on failure.
66 bool SetThreadPolicy(const std::string& scheduler_class,
67                      const std::string& partition) {
68   int error = dvrSetSchedulerClass(0, scheduler_class.c_str());
69   if (error < 0) {
70     ALOGE(
71         "SetThreadPolicy: Failed to set scheduler class \"%s\" for "
72         "thread_id=%d: %s",
73         scheduler_class.c_str(), gettid(), strerror(-error));
74     return false;
75   }
76   error = dvrSetCpuPartition(0, partition.c_str());
77   if (error < 0) {
78     ALOGE(
79         "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: "
80         "%s",
81         partition.c_str(), gettid(), strerror(-error));
82     return false;
83   }
84   return true;
85 }
86
87 }  // anonymous namespace
88
89 // Layer static data.
90 Hwc2::Composer* Layer::hwc2_hidl_;
91 const HWCDisplayMetrics* Layer::display_metrics_;
92
93 // HardwareComposer static data;
94 constexpr size_t HardwareComposer::kMaxHardwareLayers;
95
96 HardwareComposer::HardwareComposer()
97     : HardwareComposer(nullptr, RequestDisplayCallback()) {}
98
99 HardwareComposer::HardwareComposer(
100     Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback)
101     : initialized_(false),
102       hwc2_hidl_(hwc2_hidl),
103       request_display_callback_(request_display_callback),
104       callbacks_(new ComposerCallback) {}
105
106 HardwareComposer::~HardwareComposer(void) {
107   UpdatePostThreadState(PostThreadState::Quit, true);
108   if (post_thread_.joinable())
109     post_thread_.join();
110 }
111
112 bool HardwareComposer::Initialize() {
113   if (initialized_) {
114     ALOGE("HardwareComposer::Initialize: already initialized.");
115     return false;
116   }
117
118   HWC::Error error = HWC::Error::None;
119
120   Hwc2::Config config;
121   error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
122
123   if (error != HWC::Error::None) {
124     ALOGE("HardwareComposer: Failed to get current display config : %d",
125           config);
126     return false;
127   }
128
129   error =
130       GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
131
132   if (error != HWC::Error::None) {
133     ALOGE(
134         "HardwareComposer: Failed to get display attributes for current "
135         "configuration : %d",
136         error.value);
137     return false;
138   }
139
140   ALOGI(
141       "HardwareComposer: primary display attributes: width=%d height=%d "
142       "vsync_period_ns=%d DPI=%dx%d",
143       native_display_metrics_.width, native_display_metrics_.height,
144       native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
145       native_display_metrics_.dpi.y);
146
147   // Set the display metrics but never use rotation to avoid the long latency of
148   // rotation processing in hwc.
149   display_transform_ = HWC_TRANSFORM_NONE;
150   display_metrics_ = native_display_metrics_;
151
152   // Pass hwc instance and metrics to setup globals for Layer.
153   Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_);
154
155   post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
156   LOG_ALWAYS_FATAL_IF(
157       !post_thread_event_fd_,
158       "HardwareComposer: Failed to create interrupt event fd : %s",
159       strerror(errno));
160
161   post_thread_ = std::thread(&HardwareComposer::PostThread, this);
162
163   initialized_ = true;
164
165   return initialized_;
166 }
167
168 void HardwareComposer::Enable() {
169   UpdatePostThreadState(PostThreadState::Suspended, false);
170 }
171
172 void HardwareComposer::Disable() {
173   UpdatePostThreadState(PostThreadState::Suspended, true);
174 }
175
176 // Update the post thread quiescent state based on idle and suspended inputs.
177 void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
178                                              bool suspend) {
179   std::unique_lock<std::mutex> lock(post_thread_mutex_);
180
181   // Update the votes in the state variable before evaluating the effective
182   // quiescent state. Any bits set in post_thread_state_ indicate that the post
183   // thread should be suspended.
184   if (suspend) {
185     post_thread_state_ |= state;
186   } else {
187     post_thread_state_ &= ~state;
188   }
189
190   const bool quit = post_thread_state_ & PostThreadState::Quit;
191   const bool effective_suspend = post_thread_state_ != PostThreadState::Active;
192   if (quit) {
193     post_thread_quiescent_ = true;
194     eventfd_write(post_thread_event_fd_.Get(), 1);
195     post_thread_wait_.notify_one();
196   } else if (effective_suspend && !post_thread_quiescent_) {
197     post_thread_quiescent_ = true;
198     eventfd_write(post_thread_event_fd_.Get(), 1);
199   } else if (!effective_suspend && post_thread_quiescent_) {
200     post_thread_quiescent_ = false;
201     eventfd_t value;
202     eventfd_read(post_thread_event_fd_.Get(), &value);
203     post_thread_wait_.notify_one();
204   }
205
206   // Wait until the post thread is in the requested state.
207   post_thread_ready_.wait(lock, [this, effective_suspend] {
208     return effective_suspend != post_thread_resumed_;
209   });
210 }
211
212 void HardwareComposer::OnPostThreadResumed() {
213   hwc2_hidl_->resetCommands();
214
215   // HIDL HWC seems to have an internal race condition. If we submit a frame too
216   // soon after turning on VSync we don't get any VSync signals. Give poor HWC
217   // implementations a chance to enable VSync before we continue.
218   EnableVsync(false);
219   std::this_thread::sleep_for(100ms);
220   EnableVsync(true);
221   std::this_thread::sleep_for(100ms);
222
223   // TODO(skiazyk): We need to do something about accessing this directly,
224   // supposedly there is a backlight service on the way.
225   // TODO(steventhomas): When we change the backlight setting, will surface
226   // flinger (or something else) set it back to its original value once we give
227   // control of the display back to surface flinger?
228   SetBacklightBrightness(255);
229
230   // Trigger target-specific performance mode change.
231   property_set(kDvrPerformanceProperty, "performance");
232 }
233
234 void HardwareComposer::OnPostThreadPaused() {
235   retire_fence_fds_.clear();
236   display_surfaces_.clear();
237
238   for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
239     layers_[i].Reset();
240   }
241   active_layer_count_ = 0;
242
243   EnableVsync(false);
244
245   hwc2_hidl_->resetCommands();
246
247   // Trigger target-specific performance mode change.
248   property_set(kDvrPerformanceProperty, "idle");
249 }
250
251 HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
252   uint32_t num_types;
253   uint32_t num_requests;
254   HWC::Error error =
255       hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
256
257   if (error == HWC2_ERROR_HAS_CHANGES) {
258     // TODO(skiazyk): We might need to inspect the requested changes first, but
259     // so far it seems like we shouldn't ever hit a bad state.
260     // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
261     //                                               display);
262     error = hwc2_hidl_->acceptDisplayChanges(display);
263   }
264
265   return error;
266 }
267
268 int32_t HardwareComposer::EnableVsync(bool enabled) {
269   return (int32_t)hwc2_hidl_->setVsyncEnabled(
270       HWC_DISPLAY_PRIMARY,
271       (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
272                                              : HWC2_VSYNC_DISABLE));
273 }
274
275 HWC::Error HardwareComposer::Present(hwc2_display_t display) {
276   int32_t present_fence;
277   HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence);
278
279   // According to the documentation, this fence is signaled at the time of
280   // vsync/DMA for physical displays.
281   if (error == HWC::Error::None) {
282     ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
283     retire_fence_fds_.emplace_back(present_fence);
284   } else {
285     ATRACE_INT("HardwareComposer: PresentResult", error);
286   }
287
288   return error;
289 }
290
291 HWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
292                                                  hwc2_config_t config,
293                                                  hwc2_attribute_t attribute,
294                                                  int32_t* out_value) const {
295   return hwc2_hidl_->getDisplayAttribute(
296       display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
297 }
298
299 HWC::Error HardwareComposer::GetDisplayMetrics(
300     hwc2_display_t display, hwc2_config_t config,
301     HWCDisplayMetrics* out_metrics) const {
302   HWC::Error error;
303
304   error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
305                               &out_metrics->width);
306   if (error != HWC::Error::None) {
307     ALOGE(
308         "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s",
309         error.to_string().c_str());
310     return error;
311   }
312
313   error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
314                               &out_metrics->height);
315   if (error != HWC::Error::None) {
316     ALOGE(
317         "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
318         error.to_string().c_str());
319     return error;
320   }
321
322   error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
323                               &out_metrics->vsync_period_ns);
324   if (error != HWC::Error::None) {
325     ALOGE(
326         "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
327         error.to_string().c_str());
328     return error;
329   }
330
331   error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
332                               &out_metrics->dpi.x);
333   if (error != HWC::Error::None) {
334     ALOGE(
335         "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s",
336         error.to_string().c_str());
337     return error;
338   }
339
340   error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
341                               &out_metrics->dpi.y);
342   if (error != HWC::Error::None) {
343     ALOGE(
344         "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s",
345         error.to_string().c_str());
346     return error;
347   }
348
349   return HWC::Error::None;
350 }
351
352 std::string HardwareComposer::Dump() {
353   std::unique_lock<std::mutex> lock(post_thread_mutex_);
354   std::ostringstream stream;
355
356   stream << "Display metrics:     " << display_metrics_.width << "x"
357          << display_metrics_.height << " " << (display_metrics_.dpi.x / 1000.0)
358          << "x" << (display_metrics_.dpi.y / 1000.0) << " dpi @ "
359          << (1000000000.0 / display_metrics_.vsync_period_ns) << " Hz"
360          << std::endl;
361
362   stream << "Post thread resumed: " << post_thread_resumed_ << std::endl;
363   stream << "Active layers:       " << active_layer_count_ << std::endl;
364   stream << std::endl;
365
366   for (size_t i = 0; i < active_layer_count_; i++) {
367     stream << "Layer " << i << ":";
368     stream << " type=" << layers_[i].GetCompositionType().to_string();
369     stream << " surface_id=" << layers_[i].GetSurfaceId();
370     stream << " buffer_id=" << layers_[i].GetBufferId();
371     stream << std::endl;
372   }
373   stream << std::endl;
374
375   if (post_thread_resumed_) {
376     stream << "Hardware Composer Debug Info:" << std::endl;
377     stream << hwc2_hidl_->dumpDebugInfo();
378   }
379
380   return stream.str();
381 }
382
383 void HardwareComposer::PostLayers() {
384   ATRACE_NAME("HardwareComposer::PostLayers");
385
386   // Setup the hardware composer layers with current buffers.
387   for (size_t i = 0; i < active_layer_count_; i++) {
388     layers_[i].Prepare();
389   }
390
391   HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
392   if (error != HWC::Error::None) {
393     ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
394           error.to_string().c_str());
395     return;
396   }
397
398   // Now that we have taken in a frame from the application, we have a chance
399   // to drop the frame before passing the frame along to HWC.
400   // If the display driver has become backed up, we detect it here and then
401   // react by skipping this frame to catch up latency.
402   while (!retire_fence_fds_.empty() &&
403          (!retire_fence_fds_.front() ||
404           sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
405     // There are only 2 fences in here, no performance problem to shift the
406     // array of ints.
407     retire_fence_fds_.erase(retire_fence_fds_.begin());
408   }
409
410   const bool is_frame_pending = IsFramePendingInDriver();
411   const bool is_fence_pending = static_cast<int32_t>(retire_fence_fds_.size()) >
412                                 post_thread_config_.allowed_pending_fence_count;
413
414   if (is_fence_pending || is_frame_pending) {
415     ATRACE_INT("frame_skip_count", ++frame_skip_count_);
416
417     ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
418     ALOGW_IF(is_fence_pending,
419              "Warning: dropping a frame to catch up with HWC (pending = %zd)",
420              retire_fence_fds_.size());
421
422     for (size_t i = 0; i < active_layer_count_; i++) {
423       layers_[i].Drop();
424     }
425     return;
426   } else {
427     // Make the transition more obvious in systrace when the frame skip happens
428     // above.
429     ATRACE_INT("frame_skip_count", 0);
430   }
431
432 #if TRACE > 1
433   for (size_t i = 0; i < active_layer_count_; i++) {
434     ALOGI("HardwareComposer::PostLayers: layer=%zu buffer_id=%d composition=%s",
435           i, layers_[i].GetBufferId(),
436           layers_[i].GetCompositionType().to_string().c_str());
437   }
438 #endif
439
440   error = Present(HWC_DISPLAY_PRIMARY);
441   if (error != HWC::Error::None) {
442     ALOGE("HardwareComposer::PostLayers: Present failed: %s",
443           error.to_string().c_str());
444     return;
445   }
446
447   std::vector<Hwc2::Layer> out_layers;
448   std::vector<int> out_fences;
449   error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
450                                        &out_fences);
451   ALOGE_IF(error != HWC::Error::None,
452            "HardwareComposer::PostLayers: Failed to get release fences: %s",
453            error.to_string().c_str());
454
455   // Perform post-frame bookkeeping. Unused layers are a no-op.
456   uint32_t num_elements = out_layers.size();
457   for (size_t i = 0; i < num_elements; ++i) {
458     for (size_t j = 0; j < active_layer_count_; ++j) {
459       if (layers_[j].GetLayerHandle() == out_layers[i]) {
460         layers_[j].Finish(out_fences[i]);
461       }
462     }
463   }
464 }
465
466 void HardwareComposer::SetDisplaySurfaces(
467     std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) {
468   ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
469         surfaces.size());
470   const bool display_idle = surfaces.size() == 0;
471   {
472     std::unique_lock<std::mutex> lock(post_thread_mutex_);
473     pending_surfaces_ = std::move(surfaces);
474   }
475
476   if (request_display_callback_)
477     request_display_callback_(!display_idle);
478
479   // Set idle state based on whether there are any surfaces to handle.
480   UpdatePostThreadState(PostThreadState::Idle, display_idle);
481 }
482
483 int HardwareComposer::OnNewGlobalBuffer(DvrGlobalBufferKey key,
484                                         IonBuffer& ion_buffer) {
485   if (key == DvrGlobalBuffers::kVsyncBuffer) {
486     vsync_ring_ = std::make_unique<CPUMappedBroadcastRing<DvrVsyncRing>>(
487         &ion_buffer, CPUUsageMode::WRITE_OFTEN);
488
489     if (vsync_ring_->IsMapped() == false) {
490       return -EPERM;
491     }
492   }
493
494   if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
495     return MapConfigBuffer(ion_buffer);
496   }
497
498   return 0;
499 }
500
501 void HardwareComposer::OnDeletedGlobalBuffer(DvrGlobalBufferKey key) {
502   if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
503     ConfigBufferDeleted();
504   }
505 }
506
507 int HardwareComposer::MapConfigBuffer(IonBuffer& ion_buffer) {
508   std::lock_guard<std::mutex> lock(shared_config_mutex_);
509   shared_config_ring_ = DvrConfigRing();
510
511   if (ion_buffer.width() < DvrConfigRing::MemorySize()) {
512     ALOGE("HardwareComposer::MapConfigBuffer: invalid buffer size.");
513     return -EINVAL;
514   }
515
516   void* buffer_base = 0;
517   int result = ion_buffer.Lock(ion_buffer.usage(), 0, 0, ion_buffer.width(),
518                                ion_buffer.height(), &buffer_base);
519   if (result != 0) {
520     ALOGE(
521         "HardwareComposer::MapConfigBuffer: Failed to map vrflinger config "
522         "buffer.");
523     return -EPERM;
524   }
525
526   shared_config_ring_ = DvrConfigRing::Create(buffer_base, ion_buffer.width());
527   ion_buffer.Unlock();
528
529   return 0;
530 }
531
532 void HardwareComposer::ConfigBufferDeleted() {
533   std::lock_guard<std::mutex> lock(shared_config_mutex_);
534   shared_config_ring_ = DvrConfigRing();
535 }
536
537 void HardwareComposer::UpdateConfigBuffer() {
538   std::lock_guard<std::mutex> lock(shared_config_mutex_);
539   if (!shared_config_ring_.is_valid())
540     return;
541   // Copy from latest record in shared_config_ring_ to local copy.
542   DvrConfig record;
543   if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
544     post_thread_config_ = record;
545   }
546 }
547
548 int HardwareComposer::PostThreadPollInterruptible(
549     const pdx::LocalHandle& event_fd, int requested_events) {
550   pollfd pfd[2] = {
551       {
552           .fd = event_fd.Get(),
553           .events = static_cast<short>(requested_events),
554           .revents = 0,
555       },
556       {
557           .fd = post_thread_event_fd_.Get(),
558           .events = POLLPRI | POLLIN,
559           .revents = 0,
560       },
561   };
562   int ret, error;
563   do {
564     ret = poll(pfd, 2, -1);
565     error = errno;
566     ALOGW_IF(ret < 0,
567              "HardwareComposer::PostThreadPollInterruptible: Error during "
568              "poll(): %s (%d)",
569              strerror(error), error);
570   } while (ret < 0 && error == EINTR);
571
572   if (ret < 0) {
573     return -error;
574   } else if (pfd[0].revents != 0) {
575     return 0;
576   } else if (pfd[1].revents != 0) {
577     ALOGI("VrHwcPost thread interrupted");
578     return kPostThreadInterrupted;
579   } else {
580     return 0;
581   }
582 }
583
584 // Reads the value of the display driver wait_pingpong state. Returns 0 or 1
585 // (the value of the state) on success or a negative error otherwise.
586 // TODO(eieio): This is pretty driver specific, this should be moved to a
587 // separate class eventually.
588 int HardwareComposer::ReadWaitPPState() {
589   // Gracefully handle when the kernel does not support this feature.
590   if (!primary_display_wait_pp_fd_)
591     return 0;
592
593   const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
594   int ret, error;
595
596   ret = lseek(wait_pp_fd, 0, SEEK_SET);
597   if (ret < 0) {
598     error = errno;
599     ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
600           strerror(error));
601     return -error;
602   }
603
604   char data = -1;
605   ret = read(wait_pp_fd, &data, sizeof(data));
606   if (ret < 0) {
607     error = errno;
608     ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
609           strerror(error));
610     return -error;
611   }
612
613   switch (data) {
614     case '0':
615       return 0;
616     case '1':
617       return 1;
618     default:
619       ALOGE(
620           "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
621           data);
622       return -EINVAL;
623   }
624 }
625
626 // Reads the timestamp of the last vsync from the display driver.
627 // TODO(eieio): This is pretty driver specific, this should be moved to a
628 // separate class eventually.
629 int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
630   const int event_fd = primary_display_vsync_event_fd_.Get();
631   int ret, error;
632
633   // The driver returns data in the form "VSYNC=<timestamp ns>".
634   std::array<char, 32> data;
635   data.fill('\0');
636
637   // Seek back to the beginning of the event file.
638   ret = lseek(event_fd, 0, SEEK_SET);
639   if (ret < 0) {
640     error = errno;
641     ALOGE(
642         "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
643         "%s",
644         strerror(error));
645     return -error;
646   }
647
648   // Read the vsync event timestamp.
649   ret = read(event_fd, data.data(), data.size());
650   if (ret < 0) {
651     error = errno;
652     ALOGE_IF(
653         error != EAGAIN,
654         "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
655         "%s",
656         strerror(error));
657     return -error;
658   }
659
660   ret = sscanf(data.data(), "VSYNC=%" PRIu64,
661                reinterpret_cast<uint64_t*>(timestamp));
662   if (ret < 0) {
663     error = errno;
664     ALOGE(
665         "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
666         "%s",
667         strerror(error));
668     return -error;
669   }
670
671   return 0;
672 }
673
674 // Blocks until the next vsync event is signaled by the display driver.
675 // TODO(eieio): This is pretty driver specific, this should be moved to a
676 // separate class eventually.
677 int HardwareComposer::BlockUntilVSync() {
678   // Vsync is signaled by POLLPRI on the fb vsync node.
679   return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI);
680 }
681
682 // Waits for the next vsync and returns the timestamp of the vsync event. If
683 // vsync already passed since the last call, returns the latest vsync timestamp
684 // instead of blocking. This method updates the last_vsync_timeout_ in the
685 // process.
686 //
687 // TODO(eieio): This is pretty driver specific, this should be moved to a
688 // separate class eventually.
689 int HardwareComposer::WaitForVSync(int64_t* timestamp) {
690   int error;
691
692   // Get the current timestamp and decide what to do.
693   while (true) {
694     int64_t current_vsync_timestamp;
695     error = ReadVSyncTimestamp(&current_vsync_timestamp);
696     if (error < 0 && error != -EAGAIN)
697       return error;
698
699     if (error == -EAGAIN) {
700       // Vsync was turned off, wait for the next vsync event.
701       error = BlockUntilVSync();
702       if (error < 0 || error == kPostThreadInterrupted)
703         return error;
704
705       // Try again to get the timestamp for this new vsync interval.
706       continue;
707     }
708
709     // Check that we advanced to a later vsync interval.
710     if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
711       *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
712       return 0;
713     }
714
715     // See how close we are to the next expected vsync. If we're within 1ms,
716     // sleep for 1ms and try again.
717     const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
718     const int64_t threshold_ns = 1000000;  // 1ms
719
720     const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
721     const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
722
723     if (distance_to_vsync_est > threshold_ns) {
724       // Wait for vsync event notification.
725       error = BlockUntilVSync();
726       if (error < 0 || error == kPostThreadInterrupted)
727         return error;
728     } else {
729       // Sleep for a short time (1 millisecond) before retrying.
730       error = SleepUntil(GetSystemClockNs() + threshold_ns);
731       if (error < 0 || error == kPostThreadInterrupted)
732         return error;
733     }
734   }
735 }
736
737 int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
738   const int timer_fd = vsync_sleep_timer_fd_.Get();
739   const itimerspec wakeup_itimerspec = {
740       .it_interval = {.tv_sec = 0, .tv_nsec = 0},
741       .it_value = NsToTimespec(wakeup_timestamp),
742   };
743   int ret =
744       timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
745   int error = errno;
746   if (ret < 0) {
747     ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
748           strerror(error));
749     return -error;
750   }
751
752   return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN);
753 }
754
755 void HardwareComposer::PostThread() {
756   // NOLINTNEXTLINE(runtime/int)
757   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
758
759   // Set the scheduler to SCHED_FIFO with high priority. If this fails here
760   // there may have been a startup timing issue between this thread and
761   // performanced. Try again later when this thread becomes active.
762   bool thread_policy_setup =
763       SetThreadPolicy("graphics:high", "/system/performance");
764
765 #if ENABLE_BACKLIGHT_BRIGHTNESS
766   // TODO(hendrikw): This isn't required at the moment. It's possible that there
767   //                 is another method to access this when needed.
768   // Open the backlight brightness control sysfs node.
769   backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
770   ALOGW_IF(!backlight_brightness_fd_,
771            "HardwareComposer: Failed to open backlight brightness control: %s",
772            strerror(errno));
773 #endif  // ENABLE_BACKLIGHT_BRIGHTNESS
774
775   // Open the vsync event node for the primary display.
776   // TODO(eieio): Move this into a platform-specific class.
777   primary_display_vsync_event_fd_ =
778       LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
779   ALOGE_IF(!primary_display_vsync_event_fd_,
780            "HardwareComposer: Failed to open vsync event node for primary "
781            "display: %s",
782            strerror(errno));
783
784   // Open the wait pingpong status node for the primary display.
785   // TODO(eieio): Move this into a platform-specific class.
786   primary_display_wait_pp_fd_ =
787       LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
788   ALOGW_IF(
789       !primary_display_wait_pp_fd_,
790       "HardwareComposer: Failed to open wait_pp node for primary display: %s",
791       strerror(errno));
792
793   // Create a timerfd based on CLOCK_MONOTINIC.
794   vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
795   LOG_ALWAYS_FATAL_IF(
796       !vsync_sleep_timer_fd_,
797       "HardwareComposer: Failed to create vsync sleep timerfd: %s",
798       strerror(errno));
799
800   const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
801   const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
802
803   // TODO(jbates) Query vblank time from device, when such an API is available.
804   // This value (6.3%) was measured on A00 in low persistence mode.
805   int64_t vblank_ns = ns_per_frame * 63 / 1000;
806   int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
807
808   // Check property for overriding right eye offset value.
809   right_eye_photon_offset_ns =
810       property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
811
812   bool was_running = false;
813
814   while (1) {
815     ATRACE_NAME("HardwareComposer::PostThread");
816
817     // Check for updated config once per vsync.
818     UpdateConfigBuffer();
819
820     while (post_thread_quiescent_) {
821       std::unique_lock<std::mutex> lock(post_thread_mutex_);
822       ALOGI("HardwareComposer::PostThread: Entering quiescent state.");
823
824       // Tear down resources if necessary.
825       if (was_running)
826         OnPostThreadPaused();
827
828       was_running = false;
829       post_thread_resumed_ = false;
830       post_thread_ready_.notify_all();
831
832       if (post_thread_state_ & PostThreadState::Quit) {
833         ALOGI("HardwareComposer::PostThread: Quitting.");
834         return;
835       }
836
837       post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; });
838
839       post_thread_resumed_ = true;
840       post_thread_ready_.notify_all();
841
842       ALOGI("HardwareComposer::PostThread: Exiting quiescent state.");
843     }
844
845     if (!was_running) {
846       // Setup resources.
847       OnPostThreadResumed();
848       was_running = true;
849
850       // Try to setup the scheduler policy if it failed during startup. Only
851       // attempt to do this on transitions from inactive to active to avoid
852       // spamming the system with RPCs and log messages.
853       if (!thread_policy_setup) {
854         thread_policy_setup =
855             SetThreadPolicy("graphics:high", "/system/performance");
856       }
857     }
858
859     int64_t vsync_timestamp = 0;
860     {
861       std::array<char, 128> buf;
862       snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
863                vsync_count_ + 1);
864       ATRACE_NAME(buf.data());
865
866       const int error = WaitForVSync(&vsync_timestamp);
867       ALOGE_IF(
868           error < 0,
869           "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
870           strerror(-error));
871       // Don't bother processing this frame if a pause was requested
872       if (error == kPostThreadInterrupted)
873         continue;
874     }
875
876     ++vsync_count_;
877
878     const bool layer_config_changed = UpdateLayerConfig();
879
880     // Publish the vsync event.
881     if (vsync_ring_) {
882       DvrVsync vsync;
883       vsync.vsync_count = vsync_count_;
884       vsync.vsync_timestamp_ns = vsync_timestamp;
885       vsync.vsync_left_eye_offset_ns = photon_offset_ns;
886       vsync.vsync_right_eye_offset_ns = right_eye_photon_offset_ns;
887       vsync.vsync_period_ns = ns_per_frame;
888
889       vsync_ring_->Publish(vsync);
890     }
891
892     // Signal all of the vsync clients. Because absolute time is used for the
893     // wakeup time below, this can take a little time if necessary.
894     if (vsync_callback_)
895       vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp,
896                       /*frame_time_estimate*/ 0, vsync_count_);
897
898     {
899       // Sleep until shortly before vsync.
900       ATRACE_NAME("sleep");
901
902       const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame;
903       const int64_t now_ns = GetSystemClockNs();
904       const int64_t sleep_time_ns = display_time_est_ns - now_ns -
905                                     post_thread_config_.frame_post_offset_ns;
906       const int64_t wakeup_time_ns =
907           display_time_est_ns - post_thread_config_.frame_post_offset_ns;
908
909       ATRACE_INT64("sleep_time_ns", sleep_time_ns);
910       if (sleep_time_ns > 0) {
911         int error = SleepUntil(wakeup_time_ns);
912         ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
913                  strerror(-error));
914         if (error == kPostThreadInterrupted) {
915           if (layer_config_changed) {
916             // If the layer config changed we need to validateDisplay() even if
917             // we're going to drop the frame, to flush the Composer object's
918             // internal command buffer and apply our layer changes.
919             Validate(HWC_DISPLAY_PRIMARY);
920           }
921           continue;
922         }
923       }
924     }
925
926     PostLayers();
927   }
928 }
929
930 // Checks for changes in the surface stack and updates the layer config to
931 // accomodate the new stack.
932 bool HardwareComposer::UpdateLayerConfig() {
933   std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces;
934   {
935     std::unique_lock<std::mutex> lock(post_thread_mutex_);
936     if (pending_surfaces_.empty())
937       return false;
938
939     surfaces = std::move(pending_surfaces_);
940   }
941
942   ATRACE_NAME("UpdateLayerConfig_HwLayers");
943
944   display_surfaces_.clear();
945
946   Layer* target_layer;
947   size_t layer_index;
948   for (layer_index = 0;
949        layer_index < std::min(surfaces.size(), kMaxHardwareLayers);
950        layer_index++) {
951     // The bottom layer is opaque, other layers blend.
952     HWC::BlendMode blending =
953         layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
954     layers_[layer_index].Setup(surfaces[layer_index], blending,
955                                display_transform_, HWC::Composition::Device,
956                                layer_index);
957     display_surfaces_.push_back(surfaces[layer_index]);
958   }
959
960   // Clear unused layers.
961   for (size_t i = layer_index; i < kMaxHardwareLayers; i++)
962     layers_[i].Reset();
963
964   active_layer_count_ = layer_index;
965   ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
966            active_layer_count_);
967
968   // Any surfaces left over could not be assigned a hardware layer and will
969   // not be displayed.
970   ALOGW_IF(surfaces.size() != display_surfaces_.size(),
971            "HardwareComposer::UpdateLayerConfig: More surfaces than layers: "
972            "pending_surfaces=%zu display_surfaces=%zu",
973            surfaces.size(), display_surfaces_.size());
974
975   return true;
976 }
977
978 void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
979   vsync_callback_ = callback;
980 }
981
982 void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
983                                   hwc2_display_t /*display*/) {
984   // TODO(eieio): implement invalidate callbacks.
985 }
986
987 void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
988                                 hwc2_display_t /*display*/,
989                                 int64_t /*timestamp*/) {
990   ATRACE_NAME(__PRETTY_FUNCTION__);
991   // Intentionally empty. HWC may require a callback to be set to enable vsync
992   // signals. We bypass this callback thread by monitoring the vsync event
993   // directly, but signals still need to be enabled.
994 }
995
996 void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
997                                   hwc2_display_t /*display*/,
998                                   hwc2_connection_t /*connected*/) {
999   // TODO(eieio): implement display hotplug callbacks.
1000 }
1001
1002 void HardwareComposer::OnHardwareComposerRefresh() {
1003   // TODO(steventhomas): Handle refresh.
1004 }
1005
1006 void HardwareComposer::SetBacklightBrightness(int brightness) {
1007   if (backlight_brightness_fd_) {
1008     std::array<char, 32> text;
1009     const int length = snprintf(text.data(), text.size(), "%d", brightness);
1010     write(backlight_brightness_fd_.Get(), text.data(), length);
1011   }
1012 }
1013
1014 void Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl,
1015                               const HWCDisplayMetrics* metrics) {
1016   hwc2_hidl_ = hwc2_hidl;
1017   display_metrics_ = metrics;
1018 }
1019
1020 void Layer::Reset() {
1021   if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1022     hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1023     hardware_composer_layer_ = 0;
1024   }
1025
1026   z_order_ = 0;
1027   blending_ = HWC::BlendMode::None;
1028   transform_ = HWC::Transform::None;
1029   composition_type_ = HWC::Composition::Invalid;
1030   target_composition_type_ = composition_type_;
1031   source_ = EmptyVariant{};
1032   acquire_fence_.Close();
1033   surface_rect_functions_applied_ = false;
1034 }
1035
1036 void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
1037                   HWC::BlendMode blending, HWC::Transform transform,
1038                   HWC::Composition composition_type, size_t z_order) {
1039   Reset();
1040   z_order_ = z_order;
1041   blending_ = blending;
1042   transform_ = transform;
1043   composition_type_ = HWC::Composition::Invalid;
1044   target_composition_type_ = composition_type;
1045   source_ = SourceSurface{surface};
1046   CommonLayerSetup();
1047 }
1048
1049 void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1050                   HWC::BlendMode blending, HWC::Transform transform,
1051                   HWC::Composition composition_type, size_t z_order) {
1052   Reset();
1053   z_order_ = z_order;
1054   blending_ = blending;
1055   transform_ = transform;
1056   composition_type_ = HWC::Composition::Invalid;
1057   target_composition_type_ = composition_type;
1058   source_ = SourceBuffer{buffer};
1059   CommonLayerSetup();
1060 }
1061
1062 void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1063   if (source_.is<SourceBuffer>())
1064     std::get<SourceBuffer>(source_) = {buffer};
1065 }
1066
1067 void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; }
1068 void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; }
1069
1070 IonBuffer* Layer::GetBuffer() {
1071   struct Visitor {
1072     IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); }
1073     IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); }
1074     IonBuffer* operator()(EmptyVariant) { return nullptr; }
1075   };
1076   return source_.Visit(Visitor{});
1077 }
1078
1079 void Layer::UpdateLayerSettings() {
1080   if (!IsLayerSetup()) {
1081     ALOGE(
1082         "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update "
1083         "unused Layer!");
1084     return;
1085   }
1086
1087   HWC::Error error;
1088   hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1089
1090   error = hwc2_hidl_->setLayerCompositionType(
1091       display, hardware_composer_layer_,
1092       composition_type_.cast<Hwc2::IComposerClient::Composition>());
1093   ALOGE_IF(
1094       error != HWC::Error::None,
1095       "Layer::UpdateLayerSettings: Error setting layer composition type: %s",
1096       error.to_string().c_str());
1097
1098   error = hwc2_hidl_->setLayerBlendMode(
1099       display, hardware_composer_layer_,
1100       blending_.cast<Hwc2::IComposerClient::BlendMode>());
1101   ALOGE_IF(error != HWC::Error::None,
1102            "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
1103            error.to_string().c_str());
1104
1105   // TODO(eieio): Use surface attributes or some other mechanism to control
1106   // the layer display frame.
1107   error = hwc2_hidl_->setLayerDisplayFrame(
1108       display, hardware_composer_layer_,
1109       {0, 0, display_metrics_->width, display_metrics_->height});
1110   ALOGE_IF(error != HWC::Error::None,
1111            "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
1112            error.to_string().c_str());
1113
1114   error = hwc2_hidl_->setLayerVisibleRegion(
1115       display, hardware_composer_layer_,
1116       {{0, 0, display_metrics_->width, display_metrics_->height}});
1117   ALOGE_IF(error != HWC::Error::None,
1118            "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
1119            error.to_string().c_str());
1120
1121   error =
1122       hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
1123   ALOGE_IF(error != HWC::Error::None,
1124            "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
1125            error.to_string().c_str());
1126
1127   error =
1128       hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
1129   ALOGE_IF(error != HWC::Error::None,
1130            "Layer::UpdateLayerSettings: Error setting z_ order: %s",
1131            error.to_string().c_str());
1132 }
1133
1134 void Layer::CommonLayerSetup() {
1135   HWC::Error error =
1136       hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
1137   ALOGE_IF(
1138       error != HWC::Error::None,
1139       "Layer::CommonLayerSetup: Failed to create layer on primary display: %s",
1140       error.to_string().c_str());
1141   UpdateLayerSettings();
1142 }
1143
1144 void Layer::Prepare() {
1145   int right, bottom;
1146   sp<GraphicBuffer> handle;
1147
1148   // Acquire the next buffer according to the type of source.
1149   IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
1150     std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
1151   });
1152
1153   // When a layer is first setup there may be some time before the first buffer
1154   // arrives. Setup the HWC layer as a solid color to stall for time until the
1155   // first buffer arrives. Once the first buffer arrives there will always be a
1156   // buffer for the frame even if it is old.
1157   if (!handle.get()) {
1158     if (composition_type_ == HWC::Composition::Invalid) {
1159       composition_type_ = HWC::Composition::SolidColor;
1160       hwc2_hidl_->setLayerCompositionType(
1161           HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1162           composition_type_.cast<Hwc2::IComposerClient::Composition>());
1163       Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
1164       hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1165                                 layer_color);
1166     } else {
1167       // The composition type is already set. Nothing else to do until a
1168       // buffer arrives.
1169     }
1170   } else {
1171     if (composition_type_ != target_composition_type_) {
1172       composition_type_ = target_composition_type_;
1173       hwc2_hidl_->setLayerCompositionType(
1174           HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1175           composition_type_.cast<Hwc2::IComposerClient::Composition>());
1176     }
1177
1178     HWC::Error error{HWC::Error::None};
1179     error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
1180                                        hardware_composer_layer_, 0, handle,
1181                                        acquire_fence_.Get());
1182
1183     ALOGE_IF(error != HWC::Error::None,
1184              "Layer::Prepare: Error setting layer buffer: %s",
1185              error.to_string().c_str());
1186
1187     if (!surface_rect_functions_applied_) {
1188       const float float_right = right;
1189       const float float_bottom = bottom;
1190       error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1191                                              hardware_composer_layer_,
1192                                              {0, 0, float_right, float_bottom});
1193
1194       ALOGE_IF(error != HWC::Error::None,
1195                "Layer::Prepare: Error setting layer source crop: %s",
1196                error.to_string().c_str());
1197
1198       surface_rect_functions_applied_ = true;
1199     }
1200   }
1201 }
1202
1203 void Layer::Finish(int release_fence_fd) {
1204   IfAnyOf<SourceSurface, SourceBuffer>::Call(
1205       &source_, [release_fence_fd](auto& source) {
1206         source.Finish(LocalHandle(release_fence_fd));
1207       });
1208 }
1209
1210 void Layer::Drop() { acquire_fence_.Close(); }
1211
1212 }  // namespace dvr
1213 }  // namespace android