blob: 18ff4f5877aa9a54dd2159ef2ba45d9c4b628eee [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
234 // Associate each Layer instance with a hardware composer layer.
235 for (auto layer : layers_) {
236 layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
237 }
238
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800239 // Connect to pose service.
240 pose_client_ = dvrPoseCreate();
241 ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
242
Steven Thomas050b2c82017-03-06 11:45:16 -0800243 EnableVsync(true);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800244
Steven Thomas050b2c82017-03-06 11:45:16 -0800245 // TODO(skiazyk): We need to do something about accessing this directly,
246 // supposedly there is a backlight service on the way.
247 // TODO(steventhomas): When we change the backlight setting, will surface
248 // flinger (or something else) set it back to its original value once we give
249 // control of the display back to surface flinger?
250 SetBacklightBrightness(255);
Steven Thomas282a5ed2017-02-07 18:07:01 -0800251
Steven Thomas050b2c82017-03-06 11:45:16 -0800252 // Initialize the GPU compositor.
253 LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
254 "Failed to initialize the compositor");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800255
Steven Thomas050b2c82017-03-06 11:45:16 -0800256 // Trigger target-specific performance mode change.
257 property_set(kDvrPerformanceProperty, "performance");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800258}
259
Steven Thomas050b2c82017-03-06 11:45:16 -0800260void HardwareComposer::OnPostThreadPaused() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800261 retire_fence_fds_.clear();
262 gpu_layer_ = nullptr;
263
Steven Thomas050b2c82017-03-06 11:45:16 -0800264 // We have to destroy the layers to fully clear hwc device state before
265 // handing off back to surface flinger
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800266 for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
267 layers_[i]->Reset();
268 }
269
270 active_layer_count_ = 0;
271
272 framebuffer_target_.reset();
273
Steven Thomas050b2c82017-03-06 11:45:16 -0800274 display_surfaces_.clear();
275 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800276
Steven Thomas050b2c82017-03-06 11:45:16 -0800277 // Since we're clearing display_surfaces_ we'll need an update.
278 active_surfaces_updated_ = true;
279
280 if (pose_client_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800281 dvrPoseDestroy(pose_client_);
Steven Thomas050b2c82017-03-06 11:45:16 -0800282 pose_client_ = nullptr;
283 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800284
Steven Thomas050b2c82017-03-06 11:45:16 -0800285 EnableVsync(false);
286
287 frame_time_history_.ResetWithSeed(GuessFrameTime(0));
288 frame_time_backlog_.clear();
289
290 compositor_.Shutdown();
291
292 // Trigger target-specific performance mode change.
293 property_set(kDvrPerformanceProperty, "idle");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800294}
295
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800296DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
297 vec2i screen_size(display_metrics_.width, display_metrics_.height);
298 DisplayOrientation orientation =
299 (display_metrics_.width > display_metrics_.height
300 ? DisplayOrientation::kLandscape
301 : DisplayOrientation::kPortrait);
302 float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
303 float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
304 float meters_per_pixel_x = kMetersPerInch / dpi_x;
305 float meters_per_pixel_y = kMetersPerInch / dpi_y;
306 vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
307 double frame_duration_s =
308 static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
309 // TODO(hendrikw): Hard coding to 3mm. The Pixel is actually 4mm, but it
310 // seems that their tray to lens distance is wrong too, which
311 // offsets this, at least for the pixel.
312 float border_size = 0.003f;
313 return DisplayMetrics(screen_size, meters_per_pixel, border_size,
314 static_cast<float>(frame_duration_s), orientation);
315}
316
317int32_t HardwareComposer::Validate(hwc2_display_t display) {
318 uint32_t num_types;
319 uint32_t num_requests;
320 int32_t error =
321 (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
322
323 if (error == HWC2_ERROR_HAS_CHANGES) {
324 // TODO(skiazyk): We might need to inspect the requested changes first, but
325 // so far it seems like we shouldn't ever hit a bad state.
326 // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
327 // display);
328 error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
329 }
330
331 return error;
332}
333
334int32_t HardwareComposer::EnableVsync(bool enabled) {
335 return (int32_t)hwc2_hidl_->setVsyncEnabled(
336 HWC_DISPLAY_PRIMARY,
337 (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
338 : HWC2_VSYNC_DISABLE));
339}
340
341int32_t HardwareComposer::Present(hwc2_display_t display) {
342 int32_t present_fence;
343 int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
344
345 // According to the documentation, this fence is signaled at the time of
346 // vsync/DMA for physical displays.
347 if (error == HWC2_ERROR_NONE) {
348 ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
349 retire_fence_fds_.emplace_back(present_fence);
350 } else {
351 ATRACE_INT("HardwareComposer: PresentResult", error);
352 }
353
354 return error;
355}
356
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800357int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
358 hwc2_config_t config,
359 hwc2_attribute_t attribute,
360 int32_t* out_value) const {
361 return (int32_t)hwc2_hidl_->getDisplayAttribute(
362 display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
363}
364
365int32_t HardwareComposer::GetDisplayMetrics(
366 hwc2_display_t display, hwc2_config_t config,
367 HWCDisplayMetrics* out_metrics) const {
368 int32_t ret = HWC2_ERROR_NONE;
369
370 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
371 &out_metrics->width);
372 if (ret != HWC2_ERROR_NONE) {
373 ALOGE("HardwareComposer: Failed to get display width");
374 return ret;
375 }
376
377 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
378 &out_metrics->height);
379 if (ret != HWC2_ERROR_NONE) {
380 ALOGE("HardwareComposer: Failed to get display height");
381 return ret;
382 }
383
384 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
385 &out_metrics->vsync_period_ns);
386 if (ret != HWC2_ERROR_NONE) {
387 ALOGE("HardwareComposer: Failed to get display height");
388 return ret;
389 }
390
391 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
392 &out_metrics->dpi.x);
393 if (ret != HWC2_ERROR_NONE) {
394 ALOGE("HardwareComposer: Failed to get display DPI X");
395 return ret;
396 }
397
398 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
399 &out_metrics->dpi.y);
400 if (ret != HWC2_ERROR_NONE) {
401 ALOGE("HardwareComposer: Failed to get display DPI Y");
402 return ret;
403 }
404
405 return HWC2_ERROR_NONE;
406}
407
408void HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
409 std::string debug_str = hwc2_hidl_->dumpDebugInfo();
410 ALOGI("%s", debug_str.c_str());
411
412 if (buffer == nullptr) {
413 *out_size = debug_str.size();
414 } else {
415 std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
416 }
417}
418
419// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
420// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
421// there.
422void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
423 ATRACE_NAME("HardwareComposer::PostLayers");
424
425 // Setup the hardware composer layers with current buffers.
426 for (size_t i = 0; i < active_layer_count_; i++) {
427 layers_[i]->Prepare();
428 }
429
430 // Now that we have taken in a frame from the application, we have a chance
431 // to drop the frame before passing the frame along to HWC.
432 // If the display driver has become backed up, we detect it here and then
433 // react by skipping this frame to catch up latency.
434 while (!retire_fence_fds_.empty() &&
435 (!retire_fence_fds_.front() ||
436 sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
437 // There are only 2 fences in here, no performance problem to shift the
438 // array of ints.
439 retire_fence_fds_.erase(retire_fence_fds_.begin());
440 }
441
442 const bool is_frame_pending = IsFramePendingInDriver();
443 const bool is_fence_pending =
444 retire_fence_fds_.size() > kAllowedPendingFenceCount;
445
446 if (is_fence_pending || is_frame_pending) {
447 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
448
449 ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
450 ALOGW_IF(is_fence_pending,
451 "Warning: dropping a frame to catch up with HWC (pending = %zd)",
452 retire_fence_fds_.size());
453
454 for (size_t i = 0; i < active_layer_count_; i++) {
455 layers_[i]->Drop();
456 }
457 return;
458 } else {
459 // Make the transition more obvious in systrace when the frame skip happens
460 // above.
461 ATRACE_INT("frame_skip_count", 0);
462 }
463
464#if TRACE
465 for (size_t i = 0; i < active_layer_count_; i++)
466 ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
467 layers_[i]->GetCompositionType());
468#endif
469
470 int32_t ret = HWC2_ERROR_NONE;
471
472 std::vector<Hwc2::IComposerClient::Rect> full_region(1);
473 full_region[0].left = 0;
474 full_region[0].top = 0;
475 full_region[0].right = framebuffer_target_->width();
476 full_region[0].bottom = framebuffer_target_->height();
477
478 ALOGE_IF(ret, "Error setting client target : %d", ret);
479
480 ret = Validate(HWC_DISPLAY_PRIMARY);
481 if (ret) {
482 ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
483 return;
484 }
485
486 ret = Present(HWC_DISPLAY_PRIMARY);
487 if (ret) {
488 ALOGE("HardwareComposer::Present failed; ret=%d", ret);
489 return;
490 }
491
492 std::vector<Hwc2::Layer> out_layers;
493 std::vector<int> out_fences;
494 ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
495 &out_fences);
496 uint32_t num_elements = out_layers.size();
497
498 ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
499
500 // Perform post-frame bookkeeping. Unused layers are a no-op.
501 for (size_t i = 0; i < num_elements; ++i) {
502 for (size_t j = 0; j < active_layer_count_; ++j) {
503 if (layers_[j]->GetLayerHandle() == out_layers[i]) {
504 layers_[j]->Finish(out_fences[i]);
505 }
506 }
507 }
508}
509
Steven Thomas050b2c82017-03-06 11:45:16 -0800510void HardwareComposer::SetDisplaySurfaces(
Jin Qian7480c062017-03-21 00:04:15 +0000511 std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
Jin Qian7480c062017-03-21 00:04:15 +0000512 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
513 surfaces.size());
Steven Thomas050b2c82017-03-06 11:45:16 -0800514 std::unique_lock<std::mutex> lock(post_thread_mutex_);
515 active_surfaces_ = std::move(surfaces);
516 active_surfaces_updated_ = true;
517 if (post_thread_enabled_)
518 post_thread_cond_var_.notify_all();
519}
Jin Qian7480c062017-03-21 00:04:15 +0000520
Steven Thomas66747c12017-03-22 18:45:31 -0700521int HardwareComposer::PostThreadPollInterruptible(int event_fd,
522 int requested_events) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800523 pollfd pfd[2] = {
524 {
Steven Thomas66747c12017-03-22 18:45:31 -0700525 .fd = event_fd,
526 .events = static_cast<short>(requested_events),
527 .revents = 0,
Steven Thomas050b2c82017-03-06 11:45:16 -0800528 },
529 {
530 .fd = post_thread_interrupt_event_fd_.Get(),
531 .events = POLLPRI | POLLIN,
532 .revents = 0,
533 },
534 };
535 int ret, error;
536 do {
537 ret = poll(pfd, 2, -1);
538 error = errno;
539 ALOGW_IF(ret < 0,
540 "HardwareComposer::PostThreadPollInterruptible: Error during "
541 "poll(): %s (%d)",
542 strerror(error), error);
543 } while (ret < 0 && error == EINTR);
544
545 if (ret < 0) {
546 return -error;
547 } else if (pfd[0].revents != 0) {
548 return 0;
549 } else if (pfd[1].revents != 0) {
550 ALOGI("VrHwcPost thread interrupted");
551 return kPostThreadInterrupted;
552 } else {
553 return 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800554 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800555}
556
557// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
558// (the value of the state) on success or a negative error otherwise.
559// TODO(eieio): This is pretty driver specific, this should be moved to a
560// separate class eventually.
561int HardwareComposer::ReadWaitPPState() {
562 // Gracefully handle when the kernel does not support this feature.
563 if (!primary_display_wait_pp_fd_)
564 return 0;
565
566 const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
567 int ret, error;
568
569 ret = lseek(wait_pp_fd, 0, SEEK_SET);
570 if (ret < 0) {
571 error = errno;
572 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
573 strerror(error));
574 return -error;
575 }
576
577 char data = -1;
578 ret = read(wait_pp_fd, &data, sizeof(data));
579 if (ret < 0) {
580 error = errno;
581 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
582 strerror(error));
583 return -error;
584 }
585
586 switch (data) {
587 case '0':
588 return 0;
589 case '1':
590 return 1;
591 default:
592 ALOGE(
593 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
594 data);
595 return -EINVAL;
596 }
597}
598
599// Reads the timestamp of the last vsync from the display driver.
600// TODO(eieio): This is pretty driver specific, this should be moved to a
601// separate class eventually.
602int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
603 const int event_fd = primary_display_vsync_event_fd_.Get();
604 int ret, error;
605
606 // The driver returns data in the form "VSYNC=<timestamp ns>".
607 std::array<char, 32> data;
608 data.fill('\0');
609
610 // Seek back to the beginning of the event file.
611 ret = lseek(event_fd, 0, SEEK_SET);
612 if (ret < 0) {
613 error = errno;
614 ALOGE(
615 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
616 "%s",
617 strerror(error));
618 return -error;
619 }
620
621 // Read the vsync event timestamp.
622 ret = read(event_fd, data.data(), data.size());
623 if (ret < 0) {
624 error = errno;
625 ALOGE_IF(
626 error != EAGAIN,
627 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
628 "%s",
629 strerror(error));
630 return -error;
631 }
632
633 ret = sscanf(data.data(), "VSYNC=%" PRIu64,
634 reinterpret_cast<uint64_t*>(timestamp));
635 if (ret < 0) {
636 error = errno;
637 ALOGE(
638 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
639 "%s",
640 strerror(error));
641 return -error;
642 }
643
644 return 0;
645}
646
647// Blocks until the next vsync event is signaled by the display driver.
648// TODO(eieio): This is pretty driver specific, this should be moved to a
649// separate class eventually.
Steven Thomas050b2c82017-03-06 11:45:16 -0800650int HardwareComposer::BlockUntilVSync() {
Steven Thomas66747c12017-03-22 18:45:31 -0700651 return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get(),
652 // There will be a POLLPRI event on vsync
653 POLLPRI);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800654}
655
656// Waits for the next vsync and returns the timestamp of the vsync event. If
657// vsync already passed since the last call, returns the latest vsync timestamp
658// instead of blocking. This method updates the last_vsync_timeout_ in the
659// process.
660//
661// TODO(eieio): This is pretty driver specific, this should be moved to a
662// separate class eventually.
663int HardwareComposer::WaitForVSync(int64_t* timestamp) {
664 int error;
665
666 // Get the current timestamp and decide what to do.
667 while (true) {
668 int64_t current_vsync_timestamp;
669 error = ReadVSyncTimestamp(&current_vsync_timestamp);
670 if (error < 0 && error != -EAGAIN)
671 return error;
672
673 if (error == -EAGAIN) {
674 // Vsync was turned off, wait for the next vsync event.
Steven Thomas050b2c82017-03-06 11:45:16 -0800675 error = BlockUntilVSync();
676 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800677 return error;
678
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800679 // Try again to get the timestamp for this new vsync interval.
680 continue;
681 }
682
683 // Check that we advanced to a later vsync interval.
684 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
685 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
686 return 0;
687 }
688
689 // See how close we are to the next expected vsync. If we're within 1ms,
690 // sleep for 1ms and try again.
691 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
692 const int64_t threshold_ns = 1000000;
693
694 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
695 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
696
697 if (distance_to_vsync_est > threshold_ns) {
698 // Wait for vsync event notification.
Steven Thomas050b2c82017-03-06 11:45:16 -0800699 error = BlockUntilVSync();
700 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800701 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800702 } else {
Steven Thomas050b2c82017-03-06 11:45:16 -0800703 // Sleep for a short time (1 millisecond) before retrying.
704 error = SleepUntil(GetSystemClockNs() + 1000000);
705 if (error < 0 || error == kPostThreadInterrupted)
706 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800707 }
708 }
709}
710
711int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
712 const int timer_fd = vsync_sleep_timer_fd_.Get();
713 const itimerspec wakeup_itimerspec = {
714 .it_interval = {.tv_sec = 0, .tv_nsec = 0},
715 .it_value = NsToTimespec(wakeup_timestamp),
716 };
717 int ret =
718 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
719 int error = errno;
720 if (ret < 0) {
721 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
722 strerror(error));
723 return -error;
724 }
725
Steven Thomas66747c12017-03-22 18:45:31 -0700726 return PostThreadPollInterruptible(timer_fd, POLLIN);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800727}
728
729void HardwareComposer::PostThread() {
730 // NOLINTNEXTLINE(runtime/int)
Steven Thomas050b2c82017-03-06 11:45:16 -0800731 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800732
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800733 // Set the scheduler to SCHED_FIFO with high priority.
734 int error = dvrSetSchedulerClass(0, "graphics:high");
735 LOG_ALWAYS_FATAL_IF(
736 error < 0,
737 "HardwareComposer::PostThread: Failed to set scheduler class: %s",
738 strerror(-error));
739 error = dvrSetCpuPartition(0, "/system/performance");
740 LOG_ALWAYS_FATAL_IF(
741 error < 0,
742 "HardwareComposer::PostThread: Failed to set cpu partition: %s",
743 strerror(-error));
744
Steven Thomas050b2c82017-03-06 11:45:16 -0800745#if ENABLE_BACKLIGHT_BRIGHTNESS
746 // TODO(hendrikw): This isn't required at the moment. It's possible that there
747 // is another method to access this when needed.
748 // Open the backlight brightness control sysfs node.
749 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
750 ALOGW_IF(!backlight_brightness_fd_,
751 "HardwareComposer: Failed to open backlight brightness control: %s",
752 strerror(errno));
753#endif // ENABLE_BACKLIGHT_BRIGHTNESS
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800754
Steven Thomas050b2c82017-03-06 11:45:16 -0800755 // Open the vsync event node for the primary display.
756 // TODO(eieio): Move this into a platform-specific class.
757 primary_display_vsync_event_fd_ =
758 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
759 ALOGE_IF(!primary_display_vsync_event_fd_,
760 "HardwareComposer: Failed to open vsync event node for primary "
761 "display: %s",
762 strerror(errno));
763
764 // Open the wait pingpong status node for the primary display.
765 // TODO(eieio): Move this into a platform-specific class.
766 primary_display_wait_pp_fd_ =
767 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
768 ALOGW_IF(
769 !primary_display_wait_pp_fd_,
770 "HardwareComposer: Failed to open wait_pp node for primary display: %s",
771 strerror(errno));
772
773 // Create a timerfd based on CLOCK_MONOTINIC.
774 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
775 LOG_ALWAYS_FATAL_IF(
776 !vsync_sleep_timer_fd_,
777 "HardwareComposer: Failed to create vsync sleep timerfd: %s",
778 strerror(errno));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800779
780 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
781 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
782
783 // TODO(jbates) Query vblank time from device, when such an API is available.
784 // This value (6.3%) was measured on A00 in low persistence mode.
785 int64_t vblank_ns = ns_per_frame * 63 / 1000;
786 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
787
788 // Check property for overriding right eye offset value.
789 right_eye_photon_offset_ns =
790 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
791
Steven Thomas050b2c82017-03-06 11:45:16 -0800792 compositor_surfaces_.reserve(2);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800793
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800794 constexpr int kFrameTimeBacklogMax = 2;
Steven Thomas050b2c82017-03-06 11:45:16 -0800795 frame_time_backlog_.reserve(kFrameTimeBacklogMax);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800796
797 // Storage for retrieving fence info.
798 FenceInfoBuffer fence_info_buffer;
799
Steven Thomas050b2c82017-03-06 11:45:16 -0800800 bool was_running = false;
801
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800802 while (1) {
803 ATRACE_NAME("HardwareComposer::PostThread");
804
Steven Thomas282a5ed2017-02-07 18:07:01 -0800805 {
Steven Thomas050b2c82017-03-06 11:45:16 -0800806 std::unique_lock<std::mutex> lock(post_thread_mutex_);
807 while (!post_thread_enabled_ || post_thread_quit_requested_ ||
808 !PostThreadHasWork()) {
809 if (was_running) {
810 const char* pause_reason = "unknown";
811 if (!post_thread_enabled_)
812 pause_reason = "disabled";
813 else if (post_thread_quit_requested_)
814 pause_reason = "quit requested";
815 else if (!PostThreadHasWork())
816 pause_reason = "no work";
817 ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
818 OnPostThreadPaused();
819 was_running = false;
820 }
821 post_thread_running_ = false;
822 post_thread_cond_var_.notify_all();
823 if (post_thread_quit_requested_)
824 return;
825 post_thread_cond_var_.wait(lock);
Steven Thomas282a5ed2017-02-07 18:07:01 -0800826 }
Steven Thomas050b2c82017-03-06 11:45:16 -0800827 post_thread_running_ = true;
828 }
829
830 if (!was_running) {
831 ALOGI("VrHwcPost thread resumed");
832 OnPostThreadResumed();
833 was_running = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800834 }
835
836 int64_t vsync_timestamp = 0;
837 {
838 std::array<char, 128> buf;
839 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
840 vsync_count_ + 1);
841 ATRACE_NAME(buf.data());
842
843 error = WaitForVSync(&vsync_timestamp);
844 ALOGE_IF(
845 error < 0,
846 "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
847 strerror(-error));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800848 // Don't bother processing this frame if a pause was requested
Steven Thomas050b2c82017-03-06 11:45:16 -0800849 if (error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800850 continue;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800851 }
852
853 ++vsync_count_;
854
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800855 if (pose_client_) {
856 // Signal the pose service with vsync info.
857 // Display timestamp is in the middle of scanout.
858 privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
859 vsync_timestamp + photon_offset_ns,
860 ns_per_frame, right_eye_photon_offset_ns);
861 }
862
Steven Thomas050b2c82017-03-06 11:45:16 -0800863 bool layer_config_changed = UpdateLayerConfig();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800864
Steven Thomas050b2c82017-03-06 11:45:16 -0800865 if (!was_running || layer_config_changed) {
866 frame_time_history_.ResetWithSeed(
867 GuessFrameTime(compositor_surfaces_.size()));
868 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800869 } else {
Steven Thomas050b2c82017-03-06 11:45:16 -0800870 UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
871 &fence_info_buffer, &frame_time_history_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800872 }
873
874 // Get our current best estimate at how long the next frame will take to
875 // render, based on how long previous frames took to render. Use this
876 // estimate to decide when to wake up for EDS.
877 int64_t frame_time_estimate =
Steven Thomas050b2c82017-03-06 11:45:16 -0800878 frame_time_history_.GetSampleCount() == 0
879 ? GuessFrameTime(compositor_surfaces_.size())
880 : frame_time_history_.GetAverage();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800881 frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
882 DebugHudData::data.hwc_latency = frame_time_estimate;
883
884 // Signal all of the vsync clients. Because absolute time is used for the
885 // wakeup time below, this can take a little time if necessary.
886 if (vsync_callback_)
887 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
888 vsync_count_);
889
890 {
891 // Sleep until async EDS wakeup time.
892 ATRACE_NAME("sleep");
893
894 int64_t display_time_est = vsync_timestamp + ns_per_frame;
895 int64_t now = GetSystemClockNs();
896 int64_t frame_finish_time_est = now + frame_time_estimate;
897 int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
898
899 ATRACE_INT64("sleep_time_ns", sleep_time_ns);
900 if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
901 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
902 ALOGE(
903 "HardwareComposer::PostThread: Missed frame schedule, drop "
904 "frame. Expected frame miss: %.1fms",
905 static_cast<double>(frame_finish_time_est - display_time_est) /
906 1000000);
907
908 // There are several reasons we might skip a frame, but one possibility
909 // is we mispredicted the frame time. Clear out the frame time history.
Steven Thomas050b2c82017-03-06 11:45:16 -0800910 frame_time_history_.ResetWithSeed(
911 GuessFrameTime(compositor_surfaces_.size()));
912 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800913 DebugHudData::data.hwc_frame_stats.SkipFrame();
914
915 continue;
916 } else {
917 // Make the transition more obvious in systrace when the frame skip
918 // happens above.
919 ATRACE_INT("frame_skip_count", 0);
920 }
921
922 if (sleep_time_ns > 0) {
923 error = SleepUntil(display_time_est - frame_time_estimate);
924 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
925 strerror(-error));
Steven Thomas050b2c82017-03-06 11:45:16 -0800926 if (error == kPostThreadInterrupted)
927 continue;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800928 }
929 }
930
931 DebugHudData::data.hwc_frame_stats.AddFrame();
932
933 int64_t frame_start_time = GetSystemClockNs();
934
935 // Setup the output buffer for the compositor. This needs to happen before
936 // you draw with the compositor.
937 if (gpu_layer_ != nullptr) {
938 gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
939 }
940
941 // Call PostLayers now before performing the GL code for the compositor to
942 // avoid missing the deadline that can cause the lower-level hwc to get
943 // permanently backed up.
944 PostLayers(layer_config_changed);
945
Steven Thomas050b2c82017-03-06 11:45:16 -0800946 PostCompositorBuffers();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800947
948 if (gpu_layer_ != nullptr) {
949 // Note, with scanline racing, this draw is timed along with the post
950 // layers to finish just in time.
951 LocalHandle frame_fence_fd;
952 compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
953 if (frame_fence_fd) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800954 LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800955 "Frame time backlog exceeds capacity");
Steven Thomas050b2c82017-03-06 11:45:16 -0800956 frame_time_backlog_.push_back(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800957 {frame_start_time, std::move(frame_fence_fd)});
958 }
959 } else if (!layer_config_changed) {
Steven Thomas050b2c82017-03-06 11:45:16 -0800960 frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800961 }
962
963 HandlePendingScreenshots();
964 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800965}
966
Steven Thomas050b2c82017-03-06 11:45:16 -0800967bool HardwareComposer::UpdateLayerConfig() {
968 std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
969 {
970 std::lock_guard<std::mutex> lock(post_thread_mutex_);
971 if (!active_surfaces_updated_)
972 return false;
973 old_display_surfaces = display_surfaces_;
974 display_surfaces_ = active_surfaces_;
975 active_surfaces_updated_ = false;
976 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800977
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800978 DebugHudData::data.ResetLayers();
979
Steven Thomas050b2c82017-03-06 11:45:16 -0800980 // Figure out whether we need to update hardware layers. If this surface
981 // change does not add or remove hardware layers we can avoid display hiccups
982 // by gracefully updating only the GPU compositor layers.
983 int old_gpu_layer_count = 0;
984 int new_gpu_layer_count = 0;
985 bool hardware_layers_need_update = false;
986 // Look for new hardware layers and count new GPU layers.
987 for (const auto& surface : display_surfaces_) {
988 if (!(surface->flags() &
989 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
990 ++new_gpu_layer_count;
991 else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
992 surface) == old_display_surfaces.end())
993 // This is a new hardware layer, we need to update.
994 hardware_layers_need_update = true;
995 }
996 // Look for deleted hardware layers or compositor layers.
997 for (const auto& surface : old_display_surfaces) {
998 if (!(surface->flags() &
999 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
1000 ++old_gpu_layer_count;
1001 else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
1002 surface) == display_surfaces_.end())
1003 // This is a deleted hardware layer, we need to update.
1004 hardware_layers_need_update = true;
1005 }
1006 // Check for compositor hardware layer transition.
1007 if ((!old_gpu_layer_count && new_gpu_layer_count) ||
1008 (old_gpu_layer_count && !new_gpu_layer_count))
1009 hardware_layers_need_update = true;
1010
1011 // Set the chosen layer order for all surfaces.
1012 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1013 display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
1014 }
1015
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001016 // Update compositor layers.
1017 {
1018 ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1019 compositor_.UpdateSurfaces(display_surfaces_);
Steven Thomas050b2c82017-03-06 11:45:16 -08001020 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001021 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1022 const auto& surface = display_surfaces_[i];
1023 if (!(surface->flags() &
1024 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
Steven Thomas050b2c82017-03-06 11:45:16 -08001025 compositor_surfaces_.push_back(surface);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001026 }
1027 }
1028 }
1029
Steven Thomas050b2c82017-03-06 11:45:16 -08001030 if (!hardware_layers_need_update)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001031 return true;
1032
1033 // Update hardware layers.
1034
1035 ATRACE_NAME("UpdateLayerConfig_HwLayers");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001036
1037 // Update the display layers in a non-destructive fashion.
1038
1039 // Create a map from surface id to hardware layer
1040 std::map<int, Layer*> display_surface_layers;
1041
1042 for (size_t i = 0; i < active_layer_count_; ++i) {
1043 auto layer = layers_[i];
1044 int surface_id = layer->GetSurfaceId();
1045
1046 auto found =
1047 std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1048 [surface_id](const auto& surface) {
1049 return surface->surface_id() == surface_id;
1050 });
1051
1052 if (found != display_surfaces_.end()) {
1053 display_surface_layers[surface_id] = layer;
1054 }
1055 }
1056
1057 bool has_gpu_layer = std::any_of(
1058 display_surfaces_.begin(), display_surfaces_.end(),
1059 [](const auto& surface) {
1060 return !(surface->flags() &
1061 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1062 });
1063
1064 if (!has_gpu_layer) {
1065 gpu_layer_ = nullptr;
1066 }
1067
1068 auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1069 int surface_id = layer->GetSurfaceId();
1070 if (surface_id >= 0) {
1071 return display_surface_layers.count(surface_id) > 0;
1072 } else {
1073 return has_gpu_layer;
1074 }
1075 };
1076
1077 // Compress the in-use layers to the top of the list
1078 auto part = std::partition(
1079 layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1080
1081 size_t new_active_layer_count = part - layers_.begin();
1082
1083 // Clear any unused layers
1084 for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1085 layers_[i]->Reset();
1086 }
1087
1088 active_layer_count_ = new_active_layer_count;
1089
1090 bool gpu_layer_applied = false;
1091
1092 // Create/update all of the hardware layers
1093 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1094 const auto& surface = display_surfaces_[i];
1095 bool is_hw_surface =
1096 surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1097 hwc2_blend_mode_t blending =
1098 i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1099
1100 DebugHudData::data.SetLayerInfo(
1101 i, surface->width(), surface->height(),
1102 !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1103
1104 if (!is_hw_surface && gpu_layer_applied) {
1105 continue;
1106 }
1107
1108 Layer* target_layer;
1109 bool existing_layer = false;
1110
1111 if (is_hw_surface) {
1112 auto it = display_surface_layers.find(surface->surface_id());
1113
1114 if (it != display_surface_layers.end()) {
1115 target_layer = it->second;
1116 existing_layer = true;
1117 }
1118 } else if (gpu_layer_ != nullptr) {
1119 target_layer = gpu_layer_;
1120 existing_layer = true;
1121 }
1122
1123 if (!existing_layer) {
1124 if (active_layer_count_ >= kMaxHardwareLayers) {
1125 ALOGI("HardwareComposer: More than %d hardware layers requested.",
1126 kMaxHardwareLayers);
1127 break;
1128 } else {
1129 target_layer = layers_[active_layer_count_];
1130 ++active_layer_count_;
1131 }
1132
1133 ALOGD_IF(TRACE,
1134 "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1135 "layer=%zd",
1136 surface->surface_id(), i);
1137
1138 if (is_hw_surface) {
1139 target_layer->Setup(surface, blending, display_transform_,
1140 HWC2_COMPOSITION_DEVICE, i);
1141 } else {
1142 gpu_layer_ = target_layer;
1143 target_layer->Setup(compositor_.GetBuffer(), blending,
1144 display_transform_, HWC2_COMPOSITION_DEVICE, i);
1145 }
1146 } else {
1147 ALOGD_IF(TRACE,
1148 "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1149 "-> layer=%zd",
1150 surface->surface_id(), i);
1151
1152 target_layer->SetBlending(blending);
1153 target_layer->SetZOrderIndex(i);
1154 target_layer->UpdateLayerSettings();
1155 }
1156
1157 gpu_layer_applied = !is_hw_surface;
1158 }
1159
1160 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1161 active_layer_count_);
1162
1163 return true;
1164}
1165
Steven Thomas050b2c82017-03-06 11:45:16 -08001166void HardwareComposer::PostCompositorBuffers() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001167 ATRACE_NAME("PostCompositorBuffers");
Steven Thomas050b2c82017-03-06 11:45:16 -08001168 for (const auto& surface : compositor_surfaces_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001169 compositor_.PostBuffer(surface);
1170 }
1171}
1172
1173void HardwareComposer::UpdateFrameTimeHistory(
1174 std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1175 FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1176 while (!backlog->empty()) {
1177 const auto& frame_time_record = backlog->front();
1178 int64_t end_time = 0;
1179 bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1180 fence_info_buffer, &end_time);
1181 if (frame_finished) {
1182 int64_t frame_duration = end_time - frame_time_record.start_time;
1183 history->AddSample(frame_duration);
1184 // Our backlog is tiny (2 elements), so erasing from the front is ok
1185 backlog->erase(backlog->begin());
1186 } else {
1187 break;
1188 }
1189 }
1190
1191 if (backlog->size() == static_cast<size_t>(backlog_max)) {
1192 // Yikes, something must've gone wrong if our oldest frame hasn't finished
1193 // yet. Give up on waiting for it.
1194 const auto& stale_frame_time_record = backlog->front();
1195 int64_t frame_duration =
1196 GetSystemClockNs() - stale_frame_time_record.start_time;
1197 backlog->erase(backlog->begin());
1198 history->AddSample(frame_duration);
1199 ALOGW("Frame didn't finish after %.1fms",
1200 static_cast<double>(frame_duration) / 1000000);
1201 }
1202}
1203
1204bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1205 FenceInfoBuffer* fence_info_buffer,
1206 int64_t* timestamp) {
1207 int result = -1;
1208 int sync_result = sync_wait(frame_fence_fd, 0);
1209 if (sync_result == 0) {
1210 result =
1211 GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1212 if (result < 0) {
1213 ALOGE("Failed getting signaled timestamp from fence");
1214 }
1215 } else if (errno != ETIME) {
1216 ALOGE("sync_wait on frame fence failed");
1217 }
1218 return result >= 0;
1219}
1220
1221void HardwareComposer::HandlePendingScreenshots() {
1222 // Take a screenshot of the requested layer, if available.
1223 // TODO(eieio): Look into using virtual displays to composite the layer stack
1224 // into a single output buffer that can be returned to the screenshot clients.
1225 if (active_layer_count_ > 0) {
1226 if (auto screenshot_service = ScreenshotService::GetInstance()) {
1227 if (screenshot_service->IsScreenshotRequestPending()) {
1228 ATRACE_NAME("screenshot");
1229 screenshot_service->TakeIfNeeded(layers_, compositor_);
1230 }
1231 } else {
1232 ALOGW(
1233 "HardwareComposer::HandlePendingScreenshots: Failed to get "
1234 "screenshot service!");
1235 }
1236 }
1237}
1238
1239void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1240 vsync_callback_ = callback;
1241}
1242
1243void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1244 hwc2_display_t /*display*/) {
1245 // TODO(eieio): implement invalidate callbacks.
1246}
1247
1248void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1249 hwc2_display_t /*display*/,
1250 int64_t /*timestamp*/) {
1251 ATRACE_NAME(__PRETTY_FUNCTION__);
1252 // Intentionally empty. HWC may require a callback to be set to enable vsync
1253 // signals. We bypass this callback thread by monitoring the vsync event
1254 // directly, but signals still need to be enabled.
1255}
1256
1257void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1258 hwc2_display_t /*display*/,
1259 hwc2_connection_t /*connected*/) {
1260 // TODO(eieio): implement display hotplug callbacks.
1261}
1262
Steven Thomas3cfac282017-02-06 12:29:30 -08001263void HardwareComposer::OnHardwareComposerRefresh() {
1264 // TODO(steventhomas): Handle refresh.
1265}
1266
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001267void HardwareComposer::SetBacklightBrightness(int brightness) {
1268 if (backlight_brightness_fd_) {
1269 std::array<char, 32> text;
1270 const int length = snprintf(text.data(), text.size(), "%d", brightness);
1271 write(backlight_brightness_fd_.Get(), text.data(), length);
1272 }
1273}
1274
1275Layer::Layer()
1276 : hwc2_hidl_(nullptr),
1277 surface_index_(-1),
1278 hardware_composer_layer_(0),
1279 display_metrics_(nullptr),
1280 blending_(HWC2_BLEND_MODE_NONE),
1281 transform_(HWC_TRANSFORM_NONE),
1282 composition_type_(HWC2_COMPOSITION_DEVICE),
1283 surface_rect_functions_applied_(false) {}
1284
1285void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1286 hwc2_hidl_ = hwc2_hidl;
1287 display_metrics_ = metrics;
1288}
1289
1290void Layer::Reset() {
1291 const int ret = acquired_buffer_.Release(std::move(release_fence_));
1292 ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1293 strerror(-ret));
1294
1295 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1296 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1297 hardware_composer_layer_ = 0;
1298 }
1299
1300 surface_index_ = static_cast<size_t>(-1);
1301 blending_ = HWC2_BLEND_MODE_NONE;
1302 transform_ = HWC_TRANSFORM_NONE;
1303 composition_type_ = HWC2_COMPOSITION_DEVICE;
1304 direct_buffer_ = nullptr;
1305 surface_ = nullptr;
1306 acquire_fence_fd_.Close();
1307 surface_rect_functions_applied_ = false;
1308}
1309
1310void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1311 hwc2_blend_mode_t blending, hwc_transform_t transform,
1312 hwc2_composition_t composition_type, size_t index) {
1313 Reset();
1314 surface_index_ = index;
1315 surface_ = surface;
1316 blending_ = blending;
1317 transform_ = transform;
1318 composition_type_ = composition_type;
1319 CommonLayerSetup();
1320}
1321
1322void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1323 hwc2_blend_mode_t blending, hwc_transform_t transform,
1324 hwc2_composition_t composition_type, size_t z_order) {
1325 Reset();
1326 surface_index_ = z_order;
1327 direct_buffer_ = buffer;
1328 blending_ = blending;
1329 transform_ = transform;
1330 composition_type_ = composition_type;
1331 CommonLayerSetup();
1332}
1333
1334void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1335 direct_buffer_ = buffer;
1336}
1337
1338void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1339
1340void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1341
1342IonBuffer* Layer::GetBuffer() {
1343 if (direct_buffer_)
1344 return direct_buffer_.get();
1345 else if (acquired_buffer_.IsAvailable())
1346 return acquired_buffer_.buffer()->buffer();
1347 else
1348 return nullptr;
1349}
1350
1351void Layer::UpdateLayerSettings() {
1352 if (!IsLayerSetup()) {
1353 ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1354 return;
1355 }
1356
1357 int32_t ret = HWC2_ERROR_NONE;
1358
1359 hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1360
1361 ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1362 display, hardware_composer_layer_,
1363 (Hwc2::IComposerClient::Composition)composition_type_);
1364 ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1365 ret);
1366 // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1367 // hardware_composer_layer_,
1368 // (Hwc2::IComposerClient::Transform)
1369 // transform_);
1370 // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1371
1372 // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1373 // hardware_composer_device_, display, hardware_composer_layer_,
1374 // blending_);
1375 ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1376 display, hardware_composer_layer_,
1377 (Hwc2::IComposerClient::BlendMode)blending_);
1378 ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1379
1380 Hwc2::IComposerClient::Rect display_frame;
1381 display_frame.left = 0;
1382 display_frame.top = 0;
1383 display_frame.right = display_metrics_->width;
1384 display_frame.bottom = display_metrics_->height;
1385 ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1386 display, hardware_composer_layer_, display_frame);
1387 ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1388 ret);
1389
1390 std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1391 visible_region[0] = display_frame;
1392 ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1393 display, hardware_composer_layer_, visible_region);
1394 ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1395 ret);
1396
1397 ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1398 hardware_composer_layer_, 1.0f);
1399 ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1400
1401 ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1402 surface_index_);
1403 ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1404}
1405
1406void Layer::CommonLayerSetup() {
1407 int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1408 &hardware_composer_layer_);
1409
1410 ALOGE_IF(ret,
1411 "HardwareComposer: Failed to create layer on primary display : %d",
1412 ret);
1413
1414 UpdateLayerSettings();
1415}
1416
1417void Layer::Prepare() {
1418 int right, bottom;
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001419 sp<GraphicBuffer> handle;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001420
1421 if (surface_) {
1422 // Only update the acquired buffer when one is either available or this is
1423 // the first time through.
1424 if (surface_->IsBufferAvailable()) {
1425 // If we previously set this to a solid color layer to stall for time,
1426 // revert it to a device layer.
1427 if (acquired_buffer_.IsEmpty() &&
1428 composition_type_ != HWC2_COMPOSITION_DEVICE) {
1429 composition_type_ = HWC2_COMPOSITION_DEVICE;
1430 hwc2_hidl_->setLayerCompositionType(
1431 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1432 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1433 }
1434
1435 DebugHudData::data.AddLayerFrame(surface_index_);
1436 acquired_buffer_.Release(std::move(release_fence_));
1437 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1438
1439 // Basic latency stopgap for when the application misses a frame:
1440 // If the application recovers on the 2nd or 3rd (etc) frame after
1441 // missing, this code will skip a frame to catch up by checking if
1442 // the next frame is also available.
1443 if (surface_->IsBufferAvailable()) {
1444 DebugHudData::data.SkipLayerFrame(surface_index_);
1445 ATRACE_NAME("DropToCatchUp");
1446 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1447 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1448 }
1449 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1450 } else if (acquired_buffer_.IsEmpty()) {
1451 // While we are waiting for a buffer, set this to be an empty layer
1452 if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1453 composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1454 hwc2_hidl_->setLayerCompositionType(
1455 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1456 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1457
1458 Hwc2::IComposerClient::Color layer_color = {
1459 0, 0, 0, 0,
1460 };
1461 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1462 layer_color);
1463 }
1464 return;
1465 }
1466 right = acquired_buffer_.buffer()->width();
1467 bottom = acquired_buffer_.buffer()->height();
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001468 handle = acquired_buffer_.buffer()->buffer()->buffer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001469 acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1470 } else {
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -08001471 // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
1472 // mechanism to accept distorted layers from VrCore.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001473 right = direct_buffer_->width();
1474 bottom = direct_buffer_->height();
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -04001475 handle = direct_buffer_->buffer();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001476 acquire_fence_fd_.Close();
1477 }
1478
1479 int32_t ret = HWC2_ERROR_NONE;
1480
1481 if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1482 ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001483 hardware_composer_layer_, 0,
1484 handle,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001485 acquire_fence_fd_.Get());
1486
1487 ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1488 }
1489
1490 if (!surface_rect_functions_applied_) {
1491 Hwc2::IComposerClient::FRect crop_rect = {
1492 0, 0, static_cast<float>(right), static_cast<float>(bottom),
1493 };
1494 hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1495 hardware_composer_layer_, crop_rect);
1496
1497 ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1498 ret);
1499
1500// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1501// it must/cannot be called?
1502#ifdef QCOM_BSP
1503 hwc_rect_t damage_rect = {
1504 0, 0, right, bottom,
1505 };
1506 hwc_region_t damage = {
1507 1, &damage_rect,
1508 };
1509 // ret = hwc2_funcs_->set_layer_surface_damage(
1510 // hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1511 // hardware_composer_layer_, damage);
1512 // uses a std::vector as the listing
1513 // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1514 // hardware_composer_layer_, vector here);
1515
1516 ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1517 ret);
1518#endif
1519
1520 surface_rect_functions_applied_ = true;
1521 }
1522}
1523
1524void Layer::Finish(int release_fence_fd) {
1525 release_fence_.Reset(release_fence_fd);
1526}
1527
1528void Layer::Drop() { acquire_fence_fd_.Close(); }
1529
1530} // namespace dvr
1531} // namespace android