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