blob: bac9872567cada7e75aa43704cc4b04e70164d0c [file] [log] [blame]
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001#include "hardware_composer.h"
2
3#include <log/log.h>
4#include <cutils/properties.h>
5#include <cutils/sched_policy.h>
6#include <fcntl.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 <unistd.h>
15#include <utils/Trace.h>
16
17#include <algorithm>
18#include <functional>
19#include <map>
20
21#include <dvr/performance_client_api.h>
22#include <private/dvr/clock_ns.h>
23#include <private/dvr/display_types.h>
24#include <private/dvr/pose_client_internal.h>
25#include <private/dvr/sync_util.h>
26
27#include "debug_hud_data.h"
28#include "screenshot_service.h"
29
30using android::pdx::LocalHandle;
31
32namespace android {
33namespace dvr {
34
35namespace {
36
37// If the number of pending fences goes over this count at the point when we
38// are about to submit a new frame to HWC, we will drop the frame. This should
39// be a signal that the display driver has begun queuing frames. Note that with
40// smart displays (with RAM), the fence is signaled earlier than the next vsync,
41// at the point when the DMA to the display completes. Currently we use a smart
42// display and the EDS timing coincides with zero pending fences, so this is 0.
43constexpr int kAllowedPendingFenceCount = 0;
44
45// If we think we're going to miss vsync by more than this amount, skip the
46// frame.
47constexpr int64_t kFrameSkipThresholdNs = 4000000; // 4ms
48
49// Counter PostLayers() deficiency by requiring apps to produce a frame at least
50// 2.5ms before vsync. See b/28881672.
51constexpr int64_t kFrameTimeEstimateMin = 2500000; // 2.5ms
52
53constexpr size_t kDefaultDisplayConfigCount = 32;
54
55constexpr float kMetersPerInch = 0.0254f;
56
57const char kBacklightBrightnessSysFile[] =
58 "/sys/class/leds/lcd-backlight/brightness";
59
60const char kPrimaryDisplayVSyncEventFile[] =
61 "/sys/class/graphics/fb0/vsync_event";
62
63const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";
64
65const char kDvrPerformanceProperty[] = "sys.dvr.performance";
66
Luke Song4b788322017-03-24 14:17:31 -070067const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";
Alex Vakulenkoa8a92782017-01-27 14:41:57 -080068
69// Returns our best guess for the time the compositor will spend rendering the
70// next frame.
71int64_t GuessFrameTime(int compositor_visible_layer_count) {
72 // The cost of asynchronous EDS and lens warp is currently measured at 2.5ms
73 // for one layer and 7ms for two layers, but guess a higher frame time to
74 // account for CPU overhead. This guess is only used before we've measured the
75 // actual time to render a frame for the current compositor configuration.
76 switch (compositor_visible_layer_count) {
77 case 0:
78 return 500000; // .5ms
79 case 1:
80 return 5000000; // 5ms
81 default:
82 return 10500000; // 10.5ms
83 }
84}
85
86// Get time offset from a vsync to when the pose for that vsync should be
87// predicted out to. For example, if scanout gets halfway through the frame
88// at the halfway point between vsyncs, then this could be half the period.
89// With global shutter displays, this should be changed to the offset to when
90// illumination begins. Low persistence adds a frame of latency, so we predict
91// to the center of the next frame.
92inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
93 return (vsync_period_ns * 150) / 100;
94}
95
96} // anonymous namespace
97
98HardwareComposer::HardwareComposer()
99 : HardwareComposer(nullptr) {
100}
101
102HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800103 : initialized_(false),
104 hwc2_hidl_(hwc2_hidl),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800105 display_transform_(HWC_TRANSFORM_NONE),
Steven Thomas050b2c82017-03-06 11:45:16 -0800106 active_surfaces_updated_(false),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800107 active_layer_count_(0),
108 gpu_layer_(nullptr),
Steven Thomas050b2c82017-03-06 11:45:16 -0800109 post_thread_enabled_(false),
110 post_thread_running_(false),
111 post_thread_quit_requested_(false),
112 post_thread_interrupt_event_fd_(-1),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800113 backlight_brightness_fd_(-1),
114 primary_display_vsync_event_fd_(-1),
115 primary_display_wait_pp_fd_(-1),
116 vsync_sleep_timer_fd_(-1),
117 last_vsync_timestamp_(0),
118 vsync_count_(0),
119 frame_skip_count_(0),
120 pose_client_(nullptr) {
121 std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(),
122 [](auto& layer) { return &layer; });
123
124 callbacks_ = new ComposerCallback;
125}
126
127HardwareComposer::~HardwareComposer(void) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800128 std::unique_lock<std::mutex> lock(post_thread_mutex_);
129 if (post_thread_.joinable()) {
130 post_thread_quit_requested_ = true;
131 post_thread_cond_var_.notify_all();
132 post_thread_.join();
133 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800134}
135
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800136bool HardwareComposer::Initialize() {
137 if (initialized_) {
138 ALOGE("HardwareComposer::Initialize: already initialized.");
139 return false;
140 }
141
142 int32_t ret = HWC2_ERROR_NONE;
143
144 Hwc2::Config config;
145 ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
146
147 if (ret != HWC2_ERROR_NONE) {
148 ALOGE("HardwareComposer: Failed to get current display config : %d",
149 config);
150 return false;
151 }
152
153 ret =
154 GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
155
156 if (ret != HWC2_ERROR_NONE) {
157 ALOGE(
158 "HardwareComposer: Failed to get display attributes for current "
159 "configuration : %d",
160 ret);
161 return false;
162 }
163
164 ALOGI(
165 "HardwareComposer: primary display attributes: width=%d height=%d "
166 "vsync_period_ns=%d DPI=%dx%d",
167 native_display_metrics_.width, native_display_metrics_.height,
168 native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
169 native_display_metrics_.dpi.y);
170
171 // Set the display metrics but never use rotation to avoid the long latency of
172 // rotation processing in hwc.
173 display_transform_ = HWC_TRANSFORM_NONE;
174 display_metrics_ = native_display_metrics_;
175
Steven Thomas050b2c82017-03-06 11:45:16 -0800176 post_thread_interrupt_event_fd_.Reset(
177 eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
178 LOG_ALWAYS_FATAL_IF(
179 !post_thread_interrupt_event_fd_,
180 "HardwareComposer: Failed to create interrupt event fd : %s",
181 strerror(errno));
182
183 post_thread_ = std::thread(&HardwareComposer::PostThread, this);
184
Stephen Kiazyk016e5e32017-02-21 17:09:22 -0800185 initialized_ = true;
186
187 return initialized_;
188}
189
Steven Thomas050b2c82017-03-06 11:45:16 -0800190void HardwareComposer::Enable() {
191 std::lock_guard<std::mutex> lock(post_thread_mutex_);
192 post_thread_enabled_ = true;
193 post_thread_cond_var_.notify_all();
194}
195
196void HardwareComposer::Disable() {
197 std::unique_lock<std::mutex> lock(post_thread_mutex_);
198 post_thread_enabled_ = false;
199 if (post_thread_running_) {
200 // Write to the interrupt fd to get fast interrupt of the post thread
201 int error = eventfd_write(post_thread_interrupt_event_fd_.Get(), 1);
202 ALOGW_IF(error,
203 "HardwareComposer::Disable: could not write post "
204 "thread interrupt event fd : %s",
205 strerror(errno));
206
207 post_thread_cond_var_.wait(lock, [this] { return !post_thread_running_; });
208
209 // Read the interrupt fd to clear its state
210 uint64_t interrupt_count= 0;
211 error = eventfd_read(post_thread_interrupt_event_fd_.Get(),
212 &interrupt_count);
213 ALOGW_IF(error,
214 "HardwareComposer::Disable: could not read post "
215 "thread interrupt event fd : %s",
216 strerror(errno));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800217 }
Steven Thomas050b2c82017-03-06 11:45:16 -0800218}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800219
Steven Thomas050b2c82017-03-06 11:45:16 -0800220bool HardwareComposer::PostThreadHasWork() {
221 return !display_surfaces_.empty() ||
222 (active_surfaces_updated_ && !active_surfaces_.empty());
223}
Steven Thomas282a5ed2017-02-07 18:07:01 -0800224
Steven Thomas050b2c82017-03-06 11:45:16 -0800225void HardwareComposer::OnPostThreadResumed() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800226 constexpr int format = HAL_PIXEL_FORMAT_RGBA_8888;
227 constexpr int usage =
228 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER;
229
230 framebuffer_target_ = std::make_shared<IonBuffer>(
231 native_display_metrics_.width, native_display_metrics_.height, format,
232 usage);
233
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700234 hwc2_hidl_->resetCommands();
235
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800236 // Associate each Layer instance with a hardware composer layer.
237 for (auto layer : layers_) {
238 layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
239 }
240
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800241 // Connect to pose service.
242 pose_client_ = dvrPoseCreate();
243 ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
244
Steven Thomas050b2c82017-03-06 11:45:16 -0800245 EnableVsync(true);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800246
Steven Thomas050b2c82017-03-06 11:45:16 -0800247 // TODO(skiazyk): We need to do something about accessing this directly,
248 // supposedly there is a backlight service on the way.
249 // TODO(steventhomas): When we change the backlight setting, will surface
250 // flinger (or something else) set it back to its original value once we give
251 // control of the display back to surface flinger?
252 SetBacklightBrightness(255);
Steven Thomas282a5ed2017-02-07 18:07:01 -0800253
Steven Thomas050b2c82017-03-06 11:45:16 -0800254 // Initialize the GPU compositor.
255 LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
256 "Failed to initialize the compositor");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800257
Steven Thomas050b2c82017-03-06 11:45:16 -0800258 // Trigger target-specific performance mode change.
259 property_set(kDvrPerformanceProperty, "performance");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800260}
261
Steven Thomas050b2c82017-03-06 11:45:16 -0800262void HardwareComposer::OnPostThreadPaused() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800263 retire_fence_fds_.clear();
264 gpu_layer_ = nullptr;
265
Steven Thomas050b2c82017-03-06 11:45:16 -0800266 // We have to destroy the layers to fully clear hwc device state before
267 // handing off back to surface flinger
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800268 for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
269 layers_[i]->Reset();
270 }
271
272 active_layer_count_ = 0;
273
274 framebuffer_target_.reset();
275
Steven Thomas050b2c82017-03-06 11:45:16 -0800276 display_surfaces_.clear();
277 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800278
Steven Thomas050b2c82017-03-06 11:45:16 -0800279 // Since we're clearing display_surfaces_ we'll need an update.
280 active_surfaces_updated_ = true;
281
282 if (pose_client_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800283 dvrPoseDestroy(pose_client_);
Steven Thomas050b2c82017-03-06 11:45:16 -0800284 pose_client_ = nullptr;
285 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800286
Steven Thomas050b2c82017-03-06 11:45:16 -0800287 EnableVsync(false);
288
289 frame_time_history_.ResetWithSeed(GuessFrameTime(0));
290 frame_time_backlog_.clear();
291
292 compositor_.Shutdown();
293
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700294 hwc2_hidl_->resetCommands();
295
Steven Thomas050b2c82017-03-06 11:45:16 -0800296 // Trigger target-specific performance mode change.
297 property_set(kDvrPerformanceProperty, "idle");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800298}
299
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800300DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
301 vec2i screen_size(display_metrics_.width, display_metrics_.height);
302 DisplayOrientation orientation =
303 (display_metrics_.width > display_metrics_.height
304 ? DisplayOrientation::kLandscape
305 : DisplayOrientation::kPortrait);
306 float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
307 float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
308 float meters_per_pixel_x = kMetersPerInch / dpi_x;
309 float meters_per_pixel_y = kMetersPerInch / dpi_y;
310 vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
311 double frame_duration_s =
312 static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
313 // TODO(hendrikw): Hard coding to 3mm. The Pixel is actually 4mm, but it
314 // seems that their tray to lens distance is wrong too, which
315 // offsets this, at least for the pixel.
316 float border_size = 0.003f;
317 return DisplayMetrics(screen_size, meters_per_pixel, border_size,
318 static_cast<float>(frame_duration_s), orientation);
319}
320
321int32_t HardwareComposer::Validate(hwc2_display_t display) {
322 uint32_t num_types;
323 uint32_t num_requests;
324 int32_t error =
325 (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
326
327 if (error == HWC2_ERROR_HAS_CHANGES) {
328 // TODO(skiazyk): We might need to inspect the requested changes first, but
329 // so far it seems like we shouldn't ever hit a bad state.
330 // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
331 // display);
332 error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
333 }
334
335 return error;
336}
337
338int32_t HardwareComposer::EnableVsync(bool enabled) {
339 return (int32_t)hwc2_hidl_->setVsyncEnabled(
340 HWC_DISPLAY_PRIMARY,
341 (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
342 : HWC2_VSYNC_DISABLE));
343}
344
345int32_t HardwareComposer::Present(hwc2_display_t display) {
346 int32_t present_fence;
347 int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
348
349 // According to the documentation, this fence is signaled at the time of
350 // vsync/DMA for physical displays.
351 if (error == HWC2_ERROR_NONE) {
352 ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
353 retire_fence_fds_.emplace_back(present_fence);
354 } else {
355 ATRACE_INT("HardwareComposer: PresentResult", error);
356 }
357
358 return error;
359}
360
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800361int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
362 hwc2_config_t config,
363 hwc2_attribute_t attribute,
364 int32_t* out_value) const {
365 return (int32_t)hwc2_hidl_->getDisplayAttribute(
366 display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
367}
368
369int32_t HardwareComposer::GetDisplayMetrics(
370 hwc2_display_t display, hwc2_config_t config,
371 HWCDisplayMetrics* out_metrics) const {
372 int32_t ret = HWC2_ERROR_NONE;
373
374 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
375 &out_metrics->width);
376 if (ret != HWC2_ERROR_NONE) {
377 ALOGE("HardwareComposer: Failed to get display width");
378 return ret;
379 }
380
381 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
382 &out_metrics->height);
383 if (ret != HWC2_ERROR_NONE) {
384 ALOGE("HardwareComposer: Failed to get display height");
385 return ret;
386 }
387
388 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
389 &out_metrics->vsync_period_ns);
390 if (ret != HWC2_ERROR_NONE) {
391 ALOGE("HardwareComposer: Failed to get display height");
392 return ret;
393 }
394
395 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
396 &out_metrics->dpi.x);
397 if (ret != HWC2_ERROR_NONE) {
398 ALOGE("HardwareComposer: Failed to get display DPI X");
399 return ret;
400 }
401
402 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
403 &out_metrics->dpi.y);
404 if (ret != HWC2_ERROR_NONE) {
405 ALOGE("HardwareComposer: Failed to get display DPI Y");
406 return ret;
407 }
408
409 return HWC2_ERROR_NONE;
410}
411
412void HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
413 std::string debug_str = hwc2_hidl_->dumpDebugInfo();
414 ALOGI("%s", debug_str.c_str());
415
416 if (buffer == nullptr) {
417 *out_size = debug_str.size();
418 } else {
419 std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
420 }
421}
422
423// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
424// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
425// there.
426void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
427 ATRACE_NAME("HardwareComposer::PostLayers");
428
429 // Setup the hardware composer layers with current buffers.
430 for (size_t i = 0; i < active_layer_count_; i++) {
431 layers_[i]->Prepare();
432 }
433
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700434 int32_t ret = Validate(HWC_DISPLAY_PRIMARY);
435 if (ret) {
436 ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
437 return;
438 }
439
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800440 // Now that we have taken in a frame from the application, we have a chance
441 // to drop the frame before passing the frame along to HWC.
442 // If the display driver has become backed up, we detect it here and then
443 // react by skipping this frame to catch up latency.
444 while (!retire_fence_fds_.empty() &&
445 (!retire_fence_fds_.front() ||
446 sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
447 // There are only 2 fences in here, no performance problem to shift the
448 // array of ints.
449 retire_fence_fds_.erase(retire_fence_fds_.begin());
450 }
451
452 const bool is_frame_pending = IsFramePendingInDriver();
453 const bool is_fence_pending =
454 retire_fence_fds_.size() > kAllowedPendingFenceCount;
455
456 if (is_fence_pending || is_frame_pending) {
457 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
458
459 ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
460 ALOGW_IF(is_fence_pending,
461 "Warning: dropping a frame to catch up with HWC (pending = %zd)",
462 retire_fence_fds_.size());
463
464 for (size_t i = 0; i < active_layer_count_; i++) {
465 layers_[i]->Drop();
466 }
467 return;
468 } else {
469 // Make the transition more obvious in systrace when the frame skip happens
470 // above.
471 ATRACE_INT("frame_skip_count", 0);
472 }
473
474#if TRACE
475 for (size_t i = 0; i < active_layer_count_; i++)
476 ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
477 layers_[i]->GetCompositionType());
478#endif
479
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800480 ret = Present(HWC_DISPLAY_PRIMARY);
481 if (ret) {
482 ALOGE("HardwareComposer::Present failed; ret=%d", ret);
483 return;
484 }
485
486 std::vector<Hwc2::Layer> out_layers;
487 std::vector<int> out_fences;
488 ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
489 &out_fences);
490 uint32_t num_elements = out_layers.size();
491
492 ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
493
494 // Perform post-frame bookkeeping. Unused layers are a no-op.
495 for (size_t i = 0; i < num_elements; ++i) {
496 for (size_t j = 0; j < active_layer_count_; ++j) {
497 if (layers_[j]->GetLayerHandle() == out_layers[i]) {
498 layers_[j]->Finish(out_fences[i]);
499 }
500 }
501 }
502}
503
Steven Thomas050b2c82017-03-06 11:45:16 -0800504void HardwareComposer::SetDisplaySurfaces(
Jin Qian7480c062017-03-21 00:04:15 +0000505 std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
Jin Qian7480c062017-03-21 00:04:15 +0000506 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
507 surfaces.size());
Steven Thomas050b2c82017-03-06 11:45:16 -0800508 std::unique_lock<std::mutex> lock(post_thread_mutex_);
509 active_surfaces_ = std::move(surfaces);
510 active_surfaces_updated_ = true;
511 if (post_thread_enabled_)
512 post_thread_cond_var_.notify_all();
513}
Jin Qian7480c062017-03-21 00:04:15 +0000514
Steven Thomas66747c12017-03-22 18:45:31 -0700515int HardwareComposer::PostThreadPollInterruptible(int event_fd,
516 int requested_events) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800517 pollfd pfd[2] = {
518 {
Steven Thomas66747c12017-03-22 18:45:31 -0700519 .fd = event_fd,
520 .events = static_cast<short>(requested_events),
521 .revents = 0,
Steven Thomas050b2c82017-03-06 11:45:16 -0800522 },
523 {
524 .fd = post_thread_interrupt_event_fd_.Get(),
525 .events = POLLPRI | POLLIN,
526 .revents = 0,
527 },
528 };
529 int ret, error;
530 do {
531 ret = poll(pfd, 2, -1);
532 error = errno;
533 ALOGW_IF(ret < 0,
534 "HardwareComposer::PostThreadPollInterruptible: Error during "
535 "poll(): %s (%d)",
536 strerror(error), error);
537 } while (ret < 0 && error == EINTR);
538
539 if (ret < 0) {
540 return -error;
541 } else if (pfd[0].revents != 0) {
542 return 0;
543 } else if (pfd[1].revents != 0) {
544 ALOGI("VrHwcPost thread interrupted");
545 return kPostThreadInterrupted;
546 } else {
547 return 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800548 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800549}
550
551// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
552// (the value of the state) on success or a negative error otherwise.
553// TODO(eieio): This is pretty driver specific, this should be moved to a
554// separate class eventually.
555int HardwareComposer::ReadWaitPPState() {
556 // Gracefully handle when the kernel does not support this feature.
557 if (!primary_display_wait_pp_fd_)
558 return 0;
559
560 const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
561 int ret, error;
562
563 ret = lseek(wait_pp_fd, 0, SEEK_SET);
564 if (ret < 0) {
565 error = errno;
566 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
567 strerror(error));
568 return -error;
569 }
570
571 char data = -1;
572 ret = read(wait_pp_fd, &data, sizeof(data));
573 if (ret < 0) {
574 error = errno;
575 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
576 strerror(error));
577 return -error;
578 }
579
580 switch (data) {
581 case '0':
582 return 0;
583 case '1':
584 return 1;
585 default:
586 ALOGE(
587 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
588 data);
589 return -EINVAL;
590 }
591}
592
593// Reads the timestamp of the last vsync from the display driver.
594// TODO(eieio): This is pretty driver specific, this should be moved to a
595// separate class eventually.
596int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
597 const int event_fd = primary_display_vsync_event_fd_.Get();
598 int ret, error;
599
600 // The driver returns data in the form "VSYNC=<timestamp ns>".
601 std::array<char, 32> data;
602 data.fill('\0');
603
604 // Seek back to the beginning of the event file.
605 ret = lseek(event_fd, 0, SEEK_SET);
606 if (ret < 0) {
607 error = errno;
608 ALOGE(
609 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
610 "%s",
611 strerror(error));
612 return -error;
613 }
614
615 // Read the vsync event timestamp.
616 ret = read(event_fd, data.data(), data.size());
617 if (ret < 0) {
618 error = errno;
619 ALOGE_IF(
620 error != EAGAIN,
621 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
622 "%s",
623 strerror(error));
624 return -error;
625 }
626
627 ret = sscanf(data.data(), "VSYNC=%" PRIu64,
628 reinterpret_cast<uint64_t*>(timestamp));
629 if (ret < 0) {
630 error = errno;
631 ALOGE(
632 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
633 "%s",
634 strerror(error));
635 return -error;
636 }
637
638 return 0;
639}
640
641// Blocks until the next vsync event is signaled by the display driver.
642// TODO(eieio): This is pretty driver specific, this should be moved to a
643// separate class eventually.
Steven Thomas050b2c82017-03-06 11:45:16 -0800644int HardwareComposer::BlockUntilVSync() {
Steven Thomas66747c12017-03-22 18:45:31 -0700645 return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get(),
646 // There will be a POLLPRI event on vsync
647 POLLPRI);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800648}
649
650// Waits for the next vsync and returns the timestamp of the vsync event. If
651// vsync already passed since the last call, returns the latest vsync timestamp
652// instead of blocking. This method updates the last_vsync_timeout_ in the
653// process.
654//
655// TODO(eieio): This is pretty driver specific, this should be moved to a
656// separate class eventually.
657int HardwareComposer::WaitForVSync(int64_t* timestamp) {
658 int error;
659
660 // Get the current timestamp and decide what to do.
661 while (true) {
662 int64_t current_vsync_timestamp;
663 error = ReadVSyncTimestamp(&current_vsync_timestamp);
664 if (error < 0 && error != -EAGAIN)
665 return error;
666
667 if (error == -EAGAIN) {
668 // Vsync was turned off, wait for the next vsync event.
Steven Thomas050b2c82017-03-06 11:45:16 -0800669 error = BlockUntilVSync();
670 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800671 return error;
672
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800673 // Try again to get the timestamp for this new vsync interval.
674 continue;
675 }
676
677 // Check that we advanced to a later vsync interval.
678 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
679 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
680 return 0;
681 }
682
683 // See how close we are to the next expected vsync. If we're within 1ms,
684 // sleep for 1ms and try again.
685 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
686 const int64_t threshold_ns = 1000000;
687
688 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
689 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
690
691 if (distance_to_vsync_est > threshold_ns) {
692 // Wait for vsync event notification.
Steven Thomas050b2c82017-03-06 11:45:16 -0800693 error = BlockUntilVSync();
694 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800695 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800696 } else {
Steven Thomas050b2c82017-03-06 11:45:16 -0800697 // Sleep for a short time (1 millisecond) before retrying.
698 error = SleepUntil(GetSystemClockNs() + 1000000);
699 if (error < 0 || error == kPostThreadInterrupted)
700 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800701 }
702 }
703}
704
705int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
706 const int timer_fd = vsync_sleep_timer_fd_.Get();
707 const itimerspec wakeup_itimerspec = {
708 .it_interval = {.tv_sec = 0, .tv_nsec = 0},
709 .it_value = NsToTimespec(wakeup_timestamp),
710 };
711 int ret =
712 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
713 int error = errno;
714 if (ret < 0) {
715 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
716 strerror(error));
717 return -error;
718 }
719
Steven Thomas66747c12017-03-22 18:45:31 -0700720 return PostThreadPollInterruptible(timer_fd, POLLIN);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800721}
722
723void HardwareComposer::PostThread() {
724 // NOLINTNEXTLINE(runtime/int)
Steven Thomas050b2c82017-03-06 11:45:16 -0800725 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800726
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800727 // Set the scheduler to SCHED_FIFO with high priority.
728 int error = dvrSetSchedulerClass(0, "graphics:high");
729 LOG_ALWAYS_FATAL_IF(
730 error < 0,
731 "HardwareComposer::PostThread: Failed to set scheduler class: %s",
732 strerror(-error));
733 error = dvrSetCpuPartition(0, "/system/performance");
734 LOG_ALWAYS_FATAL_IF(
735 error < 0,
736 "HardwareComposer::PostThread: Failed to set cpu partition: %s",
737 strerror(-error));
738
Steven Thomas050b2c82017-03-06 11:45:16 -0800739#if ENABLE_BACKLIGHT_BRIGHTNESS
740 // TODO(hendrikw): This isn't required at the moment. It's possible that there
741 // is another method to access this when needed.
742 // Open the backlight brightness control sysfs node.
743 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
744 ALOGW_IF(!backlight_brightness_fd_,
745 "HardwareComposer: Failed to open backlight brightness control: %s",
746 strerror(errno));
747#endif // ENABLE_BACKLIGHT_BRIGHTNESS
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800748
Steven Thomas050b2c82017-03-06 11:45:16 -0800749 // Open the vsync event node for the primary display.
750 // TODO(eieio): Move this into a platform-specific class.
751 primary_display_vsync_event_fd_ =
752 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
753 ALOGE_IF(!primary_display_vsync_event_fd_,
754 "HardwareComposer: Failed to open vsync event node for primary "
755 "display: %s",
756 strerror(errno));
757
758 // Open the wait pingpong status node for the primary display.
759 // TODO(eieio): Move this into a platform-specific class.
760 primary_display_wait_pp_fd_ =
761 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
762 ALOGW_IF(
763 !primary_display_wait_pp_fd_,
764 "HardwareComposer: Failed to open wait_pp node for primary display: %s",
765 strerror(errno));
766
767 // Create a timerfd based on CLOCK_MONOTINIC.
768 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
769 LOG_ALWAYS_FATAL_IF(
770 !vsync_sleep_timer_fd_,
771 "HardwareComposer: Failed to create vsync sleep timerfd: %s",
772 strerror(errno));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800773
774 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
775 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
776
777 // TODO(jbates) Query vblank time from device, when such an API is available.
778 // This value (6.3%) was measured on A00 in low persistence mode.
779 int64_t vblank_ns = ns_per_frame * 63 / 1000;
780 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
781
782 // Check property for overriding right eye offset value.
783 right_eye_photon_offset_ns =
784 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
785
Steven Thomas050b2c82017-03-06 11:45:16 -0800786 compositor_surfaces_.reserve(2);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800787
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800788 constexpr int kFrameTimeBacklogMax = 2;
Steven Thomas050b2c82017-03-06 11:45:16 -0800789 frame_time_backlog_.reserve(kFrameTimeBacklogMax);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800790
791 // Storage for retrieving fence info.
792 FenceInfoBuffer fence_info_buffer;
793
Steven Thomas050b2c82017-03-06 11:45:16 -0800794 bool was_running = false;
795
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800796 while (1) {
797 ATRACE_NAME("HardwareComposer::PostThread");
798
Steven Thomas282a5ed2017-02-07 18:07:01 -0800799 {
Steven Thomas050b2c82017-03-06 11:45:16 -0800800 std::unique_lock<std::mutex> lock(post_thread_mutex_);
801 while (!post_thread_enabled_ || post_thread_quit_requested_ ||
802 !PostThreadHasWork()) {
803 if (was_running) {
804 const char* pause_reason = "unknown";
805 if (!post_thread_enabled_)
806 pause_reason = "disabled";
807 else if (post_thread_quit_requested_)
808 pause_reason = "quit requested";
809 else if (!PostThreadHasWork())
810 pause_reason = "no work";
811 ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
812 OnPostThreadPaused();
813 was_running = false;
814 }
815 post_thread_running_ = false;
816 post_thread_cond_var_.notify_all();
817 if (post_thread_quit_requested_)
818 return;
819 post_thread_cond_var_.wait(lock);
Steven Thomas282a5ed2017-02-07 18:07:01 -0800820 }
Steven Thomas050b2c82017-03-06 11:45:16 -0800821 post_thread_running_ = true;
822 }
823
824 if (!was_running) {
825 ALOGI("VrHwcPost thread resumed");
826 OnPostThreadResumed();
827 was_running = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800828 }
829
830 int64_t vsync_timestamp = 0;
831 {
832 std::array<char, 128> buf;
833 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
834 vsync_count_ + 1);
835 ATRACE_NAME(buf.data());
836
837 error = WaitForVSync(&vsync_timestamp);
838 ALOGE_IF(
839 error < 0,
840 "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
841 strerror(-error));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800842 // Don't bother processing this frame if a pause was requested
Steven Thomas050b2c82017-03-06 11:45:16 -0800843 if (error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800844 continue;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800845 }
846
847 ++vsync_count_;
848
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800849 if (pose_client_) {
850 // Signal the pose service with vsync info.
851 // Display timestamp is in the middle of scanout.
852 privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
853 vsync_timestamp + photon_offset_ns,
854 ns_per_frame, right_eye_photon_offset_ns);
855 }
856
Steven Thomas050b2c82017-03-06 11:45:16 -0800857 bool layer_config_changed = UpdateLayerConfig();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800858
Steven Thomas050b2c82017-03-06 11:45:16 -0800859 if (!was_running || layer_config_changed) {
860 frame_time_history_.ResetWithSeed(
861 GuessFrameTime(compositor_surfaces_.size()));
862 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800863 } else {
Steven Thomas050b2c82017-03-06 11:45:16 -0800864 UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
865 &fence_info_buffer, &frame_time_history_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800866 }
867
868 // Get our current best estimate at how long the next frame will take to
869 // render, based on how long previous frames took to render. Use this
870 // estimate to decide when to wake up for EDS.
871 int64_t frame_time_estimate =
Steven Thomas050b2c82017-03-06 11:45:16 -0800872 frame_time_history_.GetSampleCount() == 0
873 ? GuessFrameTime(compositor_surfaces_.size())
874 : frame_time_history_.GetAverage();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800875 frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
876 DebugHudData::data.hwc_latency = frame_time_estimate;
877
878 // Signal all of the vsync clients. Because absolute time is used for the
879 // wakeup time below, this can take a little time if necessary.
880 if (vsync_callback_)
881 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
882 vsync_count_);
883
884 {
885 // Sleep until async EDS wakeup time.
886 ATRACE_NAME("sleep");
887
888 int64_t display_time_est = vsync_timestamp + ns_per_frame;
889 int64_t now = GetSystemClockNs();
890 int64_t frame_finish_time_est = now + frame_time_estimate;
891 int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
892
893 ATRACE_INT64("sleep_time_ns", sleep_time_ns);
894 if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
895 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
896 ALOGE(
897 "HardwareComposer::PostThread: Missed frame schedule, drop "
898 "frame. Expected frame miss: %.1fms",
899 static_cast<double>(frame_finish_time_est - display_time_est) /
900 1000000);
901
902 // There are several reasons we might skip a frame, but one possibility
903 // is we mispredicted the frame time. Clear out the frame time history.
Steven Thomas050b2c82017-03-06 11:45:16 -0800904 frame_time_history_.ResetWithSeed(
905 GuessFrameTime(compositor_surfaces_.size()));
906 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800907 DebugHudData::data.hwc_frame_stats.SkipFrame();
908
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700909 if (layer_config_changed) {
910 // If the layer config changed we need to validateDisplay() even if
911 // we're going to drop the frame, to flush the Composer object's
912 // internal command buffer and apply our layer changes.
913 Validate(HWC_DISPLAY_PRIMARY);
914 }
915
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800916 continue;
917 } else {
918 // Make the transition more obvious in systrace when the frame skip
919 // happens above.
920 ATRACE_INT("frame_skip_count", 0);
921 }
922
923 if (sleep_time_ns > 0) {
924 error = SleepUntil(display_time_est - frame_time_estimate);
925 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
926 strerror(-error));
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700927 if (error == kPostThreadInterrupted) {
928 if (layer_config_changed) {
929 // If the layer config changed we need to validateDisplay() even if
930 // we're going to drop the frame, to flush the Composer object's
931 // internal command buffer and apply our layer changes.
932 Validate(HWC_DISPLAY_PRIMARY);
933 }
Steven Thomas050b2c82017-03-06 11:45:16 -0800934 continue;
Steven Thomas0af4b9f2017-04-26 14:34:01 -0700935 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800936 }
937 }
938
939 DebugHudData::data.hwc_frame_stats.AddFrame();
940
941 int64_t frame_start_time = GetSystemClockNs();
942
943 // Setup the output buffer for the compositor. This needs to happen before
944 // you draw with the compositor.
945 if (gpu_layer_ != nullptr) {
946 gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
947 }
948
949 // Call PostLayers now before performing the GL code for the compositor to
950 // avoid missing the deadline that can cause the lower-level hwc to get
951 // permanently backed up.
952 PostLayers(layer_config_changed);
953
Steven Thomas050b2c82017-03-06 11:45:16 -0800954 PostCompositorBuffers();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800955
956 if (gpu_layer_ != nullptr) {
957 // Note, with scanline racing, this draw is timed along with the post
958 // layers to finish just in time.
959 LocalHandle frame_fence_fd;
960 compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
961 if (frame_fence_fd) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800962 LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800963 "Frame time backlog exceeds capacity");
Steven Thomas050b2c82017-03-06 11:45:16 -0800964 frame_time_backlog_.push_back(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800965 {frame_start_time, std::move(frame_fence_fd)});
966 }
967 } else if (!layer_config_changed) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800968 frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800969 }
970
971 HandlePendingScreenshots();
972 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800973}
974
Steven Thomas050b2c82017-03-06 11:45:16 -0800975bool HardwareComposer::UpdateLayerConfig() {
976 std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
977 {
978 std::lock_guard<std::mutex> lock(post_thread_mutex_);
979 if (!active_surfaces_updated_)
980 return false;
981 old_display_surfaces = display_surfaces_;
982 display_surfaces_ = active_surfaces_;
983 active_surfaces_updated_ = false;
984 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800985
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800986 DebugHudData::data.ResetLayers();
987
Steven Thomas050b2c82017-03-06 11:45:16 -0800988 // Figure out whether we need to update hardware layers. If this surface
989 // change does not add or remove hardware layers we can avoid display hiccups
990 // by gracefully updating only the GPU compositor layers.
991 int old_gpu_layer_count = 0;
992 int new_gpu_layer_count = 0;
993 bool hardware_layers_need_update = false;
994 // Look for new hardware layers and count new GPU layers.
995 for (const auto& surface : display_surfaces_) {
996 if (!(surface->flags() &
997 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
998 ++new_gpu_layer_count;
999 else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
1000 surface) == old_display_surfaces.end())
1001 // This is a new hardware layer, we need to update.
1002 hardware_layers_need_update = true;
1003 }
1004 // Look for deleted hardware layers or compositor layers.
1005 for (const auto& surface : old_display_surfaces) {
1006 if (!(surface->flags() &
1007 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
1008 ++old_gpu_layer_count;
1009 else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
1010 surface) == display_surfaces_.end())
1011 // This is a deleted hardware layer, we need to update.
1012 hardware_layers_need_update = true;
1013 }
1014 // Check for compositor hardware layer transition.
1015 if ((!old_gpu_layer_count && new_gpu_layer_count) ||
1016 (old_gpu_layer_count && !new_gpu_layer_count))
1017 hardware_layers_need_update = true;
1018
1019 // Set the chosen layer order for all surfaces.
1020 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1021 display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
1022 }
1023
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001024 // Update compositor layers.
1025 {
1026 ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1027 compositor_.UpdateSurfaces(display_surfaces_);
Steven Thomas050b2c82017-03-06 11:45:16 -08001028 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001029 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1030 const auto& surface = display_surfaces_[i];
1031 if (!(surface->flags() &
1032 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
Steven Thomas050b2c82017-03-06 11:45:16 -08001033 compositor_surfaces_.push_back(surface);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001034 }
1035 }
1036 }
1037
Steven Thomas050b2c82017-03-06 11:45:16 -08001038 if (!hardware_layers_need_update)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001039 return true;
1040
1041 // Update hardware layers.
1042
1043 ATRACE_NAME("UpdateLayerConfig_HwLayers");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001044
1045 // Update the display layers in a non-destructive fashion.
1046
1047 // Create a map from surface id to hardware layer
1048 std::map<int, Layer*> display_surface_layers;
1049
1050 for (size_t i = 0; i < active_layer_count_; ++i) {
1051 auto layer = layers_[i];
1052 int surface_id = layer->GetSurfaceId();
1053
1054 auto found =
1055 std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1056 [surface_id](const auto& surface) {
1057 return surface->surface_id() == surface_id;
1058 });
1059
1060 if (found != display_surfaces_.end()) {
1061 display_surface_layers[surface_id] = layer;
1062 }
1063 }
1064
1065 bool has_gpu_layer = std::any_of(
1066 display_surfaces_.begin(), display_surfaces_.end(),
1067 [](const auto& surface) {
1068 return !(surface->flags() &
1069 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1070 });
1071
1072 if (!has_gpu_layer) {
1073 gpu_layer_ = nullptr;
1074 }
1075
1076 auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1077 int surface_id = layer->GetSurfaceId();
1078 if (surface_id >= 0) {
1079 return display_surface_layers.count(surface_id) > 0;
1080 } else {
1081 return has_gpu_layer;
1082 }
1083 };
1084
1085 // Compress the in-use layers to the top of the list
1086 auto part = std::partition(
1087 layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1088
1089 size_t new_active_layer_count = part - layers_.begin();
1090
1091 // Clear any unused layers
1092 for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1093 layers_[i]->Reset();
1094 }
1095
1096 active_layer_count_ = new_active_layer_count;
1097
1098 bool gpu_layer_applied = false;
1099
1100 // Create/update all of the hardware layers
1101 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1102 const auto& surface = display_surfaces_[i];
1103 bool is_hw_surface =
1104 surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1105 hwc2_blend_mode_t blending =
1106 i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1107
1108 DebugHudData::data.SetLayerInfo(
1109 i, surface->width(), surface->height(),
1110 !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1111
1112 if (!is_hw_surface && gpu_layer_applied) {
1113 continue;
1114 }
1115
1116 Layer* target_layer;
1117 bool existing_layer = false;
1118
1119 if (is_hw_surface) {
1120 auto it = display_surface_layers.find(surface->surface_id());
1121
1122 if (it != display_surface_layers.end()) {
1123 target_layer = it->second;
1124 existing_layer = true;
1125 }
1126 } else if (gpu_layer_ != nullptr) {
1127 target_layer = gpu_layer_;
1128 existing_layer = true;
1129 }
1130
1131 if (!existing_layer) {
1132 if (active_layer_count_ >= kMaxHardwareLayers) {
1133 ALOGI("HardwareComposer: More than %d hardware layers requested.",
1134 kMaxHardwareLayers);
1135 break;
1136 } else {
1137 target_layer = layers_[active_layer_count_];
1138 ++active_layer_count_;
1139 }
1140
1141 ALOGD_IF(TRACE,
1142 "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1143 "layer=%zd",
1144 surface->surface_id(), i);
1145
1146 if (is_hw_surface) {
1147 target_layer->Setup(surface, blending, display_transform_,
1148 HWC2_COMPOSITION_DEVICE, i);
1149 } else {
1150 gpu_layer_ = target_layer;
1151 target_layer->Setup(compositor_.GetBuffer(), blending,
1152 display_transform_, HWC2_COMPOSITION_DEVICE, i);
1153 }
1154 } else {
1155 ALOGD_IF(TRACE,
1156 "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1157 "-> layer=%zd",
1158 surface->surface_id(), i);
1159
1160 target_layer->SetBlending(blending);
1161 target_layer->SetZOrderIndex(i);
1162 target_layer->UpdateLayerSettings();
1163 }
1164
1165 gpu_layer_applied = !is_hw_surface;
1166 }
1167
1168 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1169 active_layer_count_);
1170
1171 return true;
1172}
1173
Steven Thomas050b2c82017-03-06 11:45:16 -08001174void HardwareComposer::PostCompositorBuffers() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001175 ATRACE_NAME("PostCompositorBuffers");
Steven Thomas050b2c82017-03-06 11:45:16 -08001176 for (const auto& surface : compositor_surfaces_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001177 compositor_.PostBuffer(surface);
1178 }
1179}
1180
1181void HardwareComposer::UpdateFrameTimeHistory(
1182 std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1183 FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1184 while (!backlog->empty()) {
1185 const auto& frame_time_record = backlog->front();
1186 int64_t end_time = 0;
1187 bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1188 fence_info_buffer, &end_time);
1189 if (frame_finished) {
1190 int64_t frame_duration = end_time - frame_time_record.start_time;
1191 history->AddSample(frame_duration);
1192 // Our backlog is tiny (2 elements), so erasing from the front is ok
1193 backlog->erase(backlog->begin());
1194 } else {
1195 break;
1196 }
1197 }
1198
1199 if (backlog->size() == static_cast<size_t>(backlog_max)) {
1200 // Yikes, something must've gone wrong if our oldest frame hasn't finished
1201 // yet. Give up on waiting for it.
1202 const auto& stale_frame_time_record = backlog->front();
1203 int64_t frame_duration =
1204 GetSystemClockNs() - stale_frame_time_record.start_time;
1205 backlog->erase(backlog->begin());
1206 history->AddSample(frame_duration);
1207 ALOGW("Frame didn't finish after %.1fms",
1208 static_cast<double>(frame_duration) / 1000000);
1209 }
1210}
1211
1212bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1213 FenceInfoBuffer* fence_info_buffer,
1214 int64_t* timestamp) {
1215 int result = -1;
1216 int sync_result = sync_wait(frame_fence_fd, 0);
1217 if (sync_result == 0) {
1218 result =
1219 GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1220 if (result < 0) {
1221 ALOGE("Failed getting signaled timestamp from fence");
1222 }
1223 } else if (errno != ETIME) {
1224 ALOGE("sync_wait on frame fence failed");
1225 }
1226 return result >= 0;
1227}
1228
1229void HardwareComposer::HandlePendingScreenshots() {
1230 // Take a screenshot of the requested layer, if available.
1231 // TODO(eieio): Look into using virtual displays to composite the layer stack
1232 // into a single output buffer that can be returned to the screenshot clients.
1233 if (active_layer_count_ > 0) {
1234 if (auto screenshot_service = ScreenshotService::GetInstance()) {
1235 if (screenshot_service->IsScreenshotRequestPending()) {
1236 ATRACE_NAME("screenshot");
1237 screenshot_service->TakeIfNeeded(layers_, compositor_);
1238 }
1239 } else {
1240 ALOGW(
1241 "HardwareComposer::HandlePendingScreenshots: Failed to get "
1242 "screenshot service!");
1243 }
1244 }
1245}
1246
1247void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1248 vsync_callback_ = callback;
1249}
1250
1251void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1252 hwc2_display_t /*display*/) {
1253 // TODO(eieio): implement invalidate callbacks.
1254}
1255
1256void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1257 hwc2_display_t /*display*/,
1258 int64_t /*timestamp*/) {
1259 ATRACE_NAME(__PRETTY_FUNCTION__);
1260 // Intentionally empty. HWC may require a callback to be set to enable vsync
1261 // signals. We bypass this callback thread by monitoring the vsync event
1262 // directly, but signals still need to be enabled.
1263}
1264
1265void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1266 hwc2_display_t /*display*/,
1267 hwc2_connection_t /*connected*/) {
1268 // TODO(eieio): implement display hotplug callbacks.
1269}
1270
Steven Thomas3cfac282017-02-06 12:29:30 -08001271void HardwareComposer::OnHardwareComposerRefresh() {
1272 // TODO(steventhomas): Handle refresh.
1273}
1274
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001275void HardwareComposer::SetBacklightBrightness(int brightness) {
1276 if (backlight_brightness_fd_) {
1277 std::array<char, 32> text;
1278 const int length = snprintf(text.data(), text.size(), "%d", brightness);
1279 write(backlight_brightness_fd_.Get(), text.data(), length);
1280 }
1281}
1282
1283Layer::Layer()
1284 : hwc2_hidl_(nullptr),
1285 surface_index_(-1),
1286 hardware_composer_layer_(0),
1287 display_metrics_(nullptr),
1288 blending_(HWC2_BLEND_MODE_NONE),
1289 transform_(HWC_TRANSFORM_NONE),
1290 composition_type_(HWC2_COMPOSITION_DEVICE),
1291 surface_rect_functions_applied_(false) {}
1292
1293void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1294 hwc2_hidl_ = hwc2_hidl;
1295 display_metrics_ = metrics;
1296}
1297
1298void Layer::Reset() {
1299 const int ret = acquired_buffer_.Release(std::move(release_fence_));
1300 ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1301 strerror(-ret));
1302
1303 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1304 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1305 hardware_composer_layer_ = 0;
1306 }
1307
1308 surface_index_ = static_cast<size_t>(-1);
1309 blending_ = HWC2_BLEND_MODE_NONE;
1310 transform_ = HWC_TRANSFORM_NONE;
1311 composition_type_ = HWC2_COMPOSITION_DEVICE;
1312 direct_buffer_ = nullptr;
1313 surface_ = nullptr;
1314 acquire_fence_fd_.Close();
1315 surface_rect_functions_applied_ = false;
1316}
1317
1318void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1319 hwc2_blend_mode_t blending, hwc_transform_t transform,
1320 hwc2_composition_t composition_type, size_t index) {
1321 Reset();
1322 surface_index_ = index;
1323 surface_ = surface;
1324 blending_ = blending;
1325 transform_ = transform;
1326 composition_type_ = composition_type;
1327 CommonLayerSetup();
1328}
1329
1330void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1331 hwc2_blend_mode_t blending, hwc_transform_t transform,
1332 hwc2_composition_t composition_type, size_t z_order) {
1333 Reset();
1334 surface_index_ = z_order;
1335 direct_buffer_ = buffer;
1336 blending_ = blending;
1337 transform_ = transform;
1338 composition_type_ = composition_type;
1339 CommonLayerSetup();
1340}
1341
1342void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1343 direct_buffer_ = buffer;
1344}
1345
1346void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1347
1348void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1349
1350IonBuffer* Layer::GetBuffer() {
1351 if (direct_buffer_)
1352 return direct_buffer_.get();
1353 else if (acquired_buffer_.IsAvailable())
1354 return acquired_buffer_.buffer()->buffer();
1355 else
1356 return nullptr;
1357}
1358
1359void Layer::UpdateLayerSettings() {
1360 if (!IsLayerSetup()) {
1361 ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1362 return;
1363 }
1364
1365 int32_t ret = HWC2_ERROR_NONE;
1366
1367 hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1368
1369 ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1370 display, hardware_composer_layer_,
1371 (Hwc2::IComposerClient::Composition)composition_type_);
1372 ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1373 ret);
1374 // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1375 // hardware_composer_layer_,
1376 // (Hwc2::IComposerClient::Transform)
1377 // transform_);
1378 // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1379
1380 // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1381 // hardware_composer_device_, display, hardware_composer_layer_,
1382 // blending_);
1383 ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1384 display, hardware_composer_layer_,
1385 (Hwc2::IComposerClient::BlendMode)blending_);
1386 ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1387
1388 Hwc2::IComposerClient::Rect display_frame;
1389 display_frame.left = 0;
1390 display_frame.top = 0;
1391 display_frame.right = display_metrics_->width;
1392 display_frame.bottom = display_metrics_->height;
1393 ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1394 display, hardware_composer_layer_, display_frame);
1395 ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1396 ret);
1397
1398 std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1399 visible_region[0] = display_frame;
1400 ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1401 display, hardware_composer_layer_, visible_region);
1402 ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1403 ret);
1404
1405 ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1406 hardware_composer_layer_, 1.0f);
1407 ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1408
1409 ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1410 surface_index_);
1411 ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1412}
1413
1414void Layer::CommonLayerSetup() {
1415 int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1416 &hardware_composer_layer_);
1417
1418 ALOGE_IF(ret,
1419 "HardwareComposer: Failed to create layer on primary display : %d",
1420 ret);
1421
1422 UpdateLayerSettings();
1423}
1424
1425void Layer::Prepare() {
1426 int right, bottom;
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001427 sp<GraphicBuffer> handle;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001428
1429 if (surface_) {
1430 // Only update the acquired buffer when one is either available or this is
1431 // the first time through.
1432 if (surface_->IsBufferAvailable()) {
1433 // If we previously set this to a solid color layer to stall for time,
1434 // revert it to a device layer.
1435 if (acquired_buffer_.IsEmpty() &&
1436 composition_type_ != HWC2_COMPOSITION_DEVICE) {
1437 composition_type_ = HWC2_COMPOSITION_DEVICE;
1438 hwc2_hidl_->setLayerCompositionType(
1439 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1440 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1441 }
1442
1443 DebugHudData::data.AddLayerFrame(surface_index_);
1444 acquired_buffer_.Release(std::move(release_fence_));
1445 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1446
1447 // Basic latency stopgap for when the application misses a frame:
1448 // If the application recovers on the 2nd or 3rd (etc) frame after
1449 // missing, this code will skip a frame to catch up by checking if
1450 // the next frame is also available.
1451 if (surface_->IsBufferAvailable()) {
1452 DebugHudData::data.SkipLayerFrame(surface_index_);
1453 ATRACE_NAME("DropToCatchUp");
1454 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1455 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1456 }
1457 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1458 } else if (acquired_buffer_.IsEmpty()) {
1459 // While we are waiting for a buffer, set this to be an empty layer
1460 if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1461 composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1462 hwc2_hidl_->setLayerCompositionType(
1463 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1464 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1465
1466 Hwc2::IComposerClient::Color layer_color = {
1467 0, 0, 0, 0,
1468 };
1469 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1470 layer_color);
1471 }
1472 return;
1473 }
1474 right = acquired_buffer_.buffer()->width();
1475 bottom = acquired_buffer_.buffer()->height();
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001476 handle = acquired_buffer_.buffer()->buffer()->buffer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001477 acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1478 } else {
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -08001479 // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
1480 // mechanism to accept distorted layers from VrCore.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001481 right = direct_buffer_->width();
1482 bottom = direct_buffer_->height();
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001483 handle = direct_buffer_->buffer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001484 acquire_fence_fd_.Close();
1485 }
1486
1487 int32_t ret = HWC2_ERROR_NONE;
1488
1489 if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1490 ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001491 hardware_composer_layer_, 0,
1492 handle,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001493 acquire_fence_fd_.Get());
1494
1495 ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1496 }
1497
1498 if (!surface_rect_functions_applied_) {
1499 Hwc2::IComposerClient::FRect crop_rect = {
1500 0, 0, static_cast<float>(right), static_cast<float>(bottom),
1501 };
1502 hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1503 hardware_composer_layer_, crop_rect);
1504
1505 ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1506 ret);
1507
1508// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1509// it must/cannot be called?
1510#ifdef QCOM_BSP
1511 hwc_rect_t damage_rect = {
1512 0, 0, right, bottom,
1513 };
1514 hwc_region_t damage = {
1515 1, &damage_rect,
1516 };
1517 // ret = hwc2_funcs_->set_layer_surface_damage(
1518 // hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1519 // hardware_composer_layer_, damage);
1520 // uses a std::vector as the listing
1521 // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1522 // hardware_composer_layer_, vector here);
1523
1524 ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1525 ret);
1526#endif
1527
1528 surface_rect_functions_applied_ = true;
1529 }
1530}
1531
1532void Layer::Finish(int release_fence_fd) {
1533 release_fence_.Reset(release_fence_fd);
1534}
1535
1536void Layer::Drop() { acquire_fence_fd_.Close(); }
1537
1538} // namespace dvr
1539} // namespace android