blob: da45859a97920735d93c0310ce021cf46e3810a2 [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
67const char kRightEyeOffsetProperty[] = "dreamos.right_eye_offset_ns";
68
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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-03-06 11:45:16 -0800218}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800219
Steven Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-03-06 11:45:16 -0800243 EnableVsync(true);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800244
Steven Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-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 Thomasf43d13e2017-03-06 11:45:16 -0800274 display_surfaces_.clear();
275 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800276
Steven Thomasf43d13e2017-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 Thomasf43d13e2017-03-06 11:45:16 -0800282 pose_client_ = nullptr;
283 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800284
Steven Thomasf43d13e2017-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 Thomasf43d13e2017-03-06 11:45:16 -0800510void HardwareComposer::SetDisplaySurfaces(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800511 std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800512 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
513 surfaces.size());
Steven Thomasf43d13e2017-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}
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800520
Steven Thomasf43d13e2017-03-06 11:45:16 -0800521int HardwareComposer::PostThreadPollInterruptible(int event_fd) {
522 pollfd pfd[2] = {
523 {
524 .fd = event_fd, .events = POLLPRI | POLLIN, .revents = 0,
525 },
526 {
527 .fd = post_thread_interrupt_event_fd_.Get(),
528 .events = POLLPRI | POLLIN,
529 .revents = 0,
530 },
531 };
532 int ret, error;
533 do {
534 ret = poll(pfd, 2, -1);
535 error = errno;
536 ALOGW_IF(ret < 0,
537 "HardwareComposer::PostThreadPollInterruptible: Error during "
538 "poll(): %s (%d)",
539 strerror(error), error);
540 } while (ret < 0 && error == EINTR);
541
542 if (ret < 0) {
543 return -error;
544 } else if (pfd[0].revents != 0) {
545 return 0;
546 } else if (pfd[1].revents != 0) {
547 ALOGI("VrHwcPost thread interrupted");
548 return kPostThreadInterrupted;
549 } else {
550 return 0;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800551 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800552}
553
554// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
555// (the value of the state) on success or a negative error otherwise.
556// TODO(eieio): This is pretty driver specific, this should be moved to a
557// separate class eventually.
558int HardwareComposer::ReadWaitPPState() {
559 // Gracefully handle when the kernel does not support this feature.
560 if (!primary_display_wait_pp_fd_)
561 return 0;
562
563 const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
564 int ret, error;
565
566 ret = lseek(wait_pp_fd, 0, SEEK_SET);
567 if (ret < 0) {
568 error = errno;
569 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
570 strerror(error));
571 return -error;
572 }
573
574 char data = -1;
575 ret = read(wait_pp_fd, &data, sizeof(data));
576 if (ret < 0) {
577 error = errno;
578 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
579 strerror(error));
580 return -error;
581 }
582
583 switch (data) {
584 case '0':
585 return 0;
586 case '1':
587 return 1;
588 default:
589 ALOGE(
590 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
591 data);
592 return -EINVAL;
593 }
594}
595
596// Reads the timestamp of the last vsync from the display driver.
597// TODO(eieio): This is pretty driver specific, this should be moved to a
598// separate class eventually.
599int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
600 const int event_fd = primary_display_vsync_event_fd_.Get();
601 int ret, error;
602
603 // The driver returns data in the form "VSYNC=<timestamp ns>".
604 std::array<char, 32> data;
605 data.fill('\0');
606
607 // Seek back to the beginning of the event file.
608 ret = lseek(event_fd, 0, SEEK_SET);
609 if (ret < 0) {
610 error = errno;
611 ALOGE(
612 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
613 "%s",
614 strerror(error));
615 return -error;
616 }
617
618 // Read the vsync event timestamp.
619 ret = read(event_fd, data.data(), data.size());
620 if (ret < 0) {
621 error = errno;
622 ALOGE_IF(
623 error != EAGAIN,
624 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
625 "%s",
626 strerror(error));
627 return -error;
628 }
629
630 ret = sscanf(data.data(), "VSYNC=%" PRIu64,
631 reinterpret_cast<uint64_t*>(timestamp));
632 if (ret < 0) {
633 error = errno;
634 ALOGE(
635 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
636 "%s",
637 strerror(error));
638 return -error;
639 }
640
641 return 0;
642}
643
644// Blocks until the next vsync event is signaled by the display driver.
645// TODO(eieio): This is pretty driver specific, this should be moved to a
646// separate class eventually.
Steven Thomasf43d13e2017-03-06 11:45:16 -0800647int HardwareComposer::BlockUntilVSync() {
648 return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get());
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800649}
650
651// Waits for the next vsync and returns the timestamp of the vsync event. If
652// vsync already passed since the last call, returns the latest vsync timestamp
653// instead of blocking. This method updates the last_vsync_timeout_ in the
654// process.
655//
656// TODO(eieio): This is pretty driver specific, this should be moved to a
657// separate class eventually.
658int HardwareComposer::WaitForVSync(int64_t* timestamp) {
659 int error;
660
661 // Get the current timestamp and decide what to do.
662 while (true) {
663 int64_t current_vsync_timestamp;
664 error = ReadVSyncTimestamp(&current_vsync_timestamp);
665 if (error < 0 && error != -EAGAIN)
666 return error;
667
668 if (error == -EAGAIN) {
669 // Vsync was turned off, wait for the next vsync event.
Steven Thomasf43d13e2017-03-06 11:45:16 -0800670 error = BlockUntilVSync();
671 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800672 return error;
673
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800674 // Try again to get the timestamp for this new vsync interval.
675 continue;
676 }
677
678 // Check that we advanced to a later vsync interval.
679 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
680 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
681 return 0;
682 }
683
684 // See how close we are to the next expected vsync. If we're within 1ms,
685 // sleep for 1ms and try again.
686 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
687 const int64_t threshold_ns = 1000000;
688
689 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
690 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
691
692 if (distance_to_vsync_est > threshold_ns) {
693 // Wait for vsync event notification.
Steven Thomasf43d13e2017-03-06 11:45:16 -0800694 error = BlockUntilVSync();
695 if (error < 0 || error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800696 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800697 } else {
Steven Thomasf43d13e2017-03-06 11:45:16 -0800698 // Sleep for a short time (1 millisecond) before retrying.
699 error = SleepUntil(GetSystemClockNs() + 1000000);
700 if (error < 0 || error == kPostThreadInterrupted)
701 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800702 }
703 }
704}
705
706int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
707 const int timer_fd = vsync_sleep_timer_fd_.Get();
708 const itimerspec wakeup_itimerspec = {
709 .it_interval = {.tv_sec = 0, .tv_nsec = 0},
710 .it_value = NsToTimespec(wakeup_timestamp),
711 };
712 int ret =
713 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
714 int error = errno;
715 if (ret < 0) {
716 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
717 strerror(error));
718 return -error;
719 }
720
Steven Thomasf43d13e2017-03-06 11:45:16 -0800721 return PostThreadPollInterruptible(timer_fd);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800722}
723
724void HardwareComposer::PostThread() {
725 // NOLINTNEXTLINE(runtime/int)
Steven Thomasf43d13e2017-03-06 11:45:16 -0800726 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800727
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800728 // Set the scheduler to SCHED_FIFO with high priority.
729 int error = dvrSetSchedulerClass(0, "graphics:high");
730 LOG_ALWAYS_FATAL_IF(
731 error < 0,
732 "HardwareComposer::PostThread: Failed to set scheduler class: %s",
733 strerror(-error));
734 error = dvrSetCpuPartition(0, "/system/performance");
735 LOG_ALWAYS_FATAL_IF(
736 error < 0,
737 "HardwareComposer::PostThread: Failed to set cpu partition: %s",
738 strerror(-error));
739
Steven Thomasf43d13e2017-03-06 11:45:16 -0800740#if ENABLE_BACKLIGHT_BRIGHTNESS
741 // TODO(hendrikw): This isn't required at the moment. It's possible that there
742 // is another method to access this when needed.
743 // Open the backlight brightness control sysfs node.
744 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
745 ALOGW_IF(!backlight_brightness_fd_,
746 "HardwareComposer: Failed to open backlight brightness control: %s",
747 strerror(errno));
748#endif // ENABLE_BACKLIGHT_BRIGHTNESS
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800749
Steven Thomasf43d13e2017-03-06 11:45:16 -0800750 // Open the vsync event node for the primary display.
751 // TODO(eieio): Move this into a platform-specific class.
752 primary_display_vsync_event_fd_ =
753 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
754 ALOGE_IF(!primary_display_vsync_event_fd_,
755 "HardwareComposer: Failed to open vsync event node for primary "
756 "display: %s",
757 strerror(errno));
758
759 // Open the wait pingpong status node for the primary display.
760 // TODO(eieio): Move this into a platform-specific class.
761 primary_display_wait_pp_fd_ =
762 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
763 ALOGW_IF(
764 !primary_display_wait_pp_fd_,
765 "HardwareComposer: Failed to open wait_pp node for primary display: %s",
766 strerror(errno));
767
768 // Create a timerfd based on CLOCK_MONOTINIC.
769 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
770 LOG_ALWAYS_FATAL_IF(
771 !vsync_sleep_timer_fd_,
772 "HardwareComposer: Failed to create vsync sleep timerfd: %s",
773 strerror(errno));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800774
775 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
776 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
777
778 // TODO(jbates) Query vblank time from device, when such an API is available.
779 // This value (6.3%) was measured on A00 in low persistence mode.
780 int64_t vblank_ns = ns_per_frame * 63 / 1000;
781 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
782
783 // Check property for overriding right eye offset value.
784 right_eye_photon_offset_ns =
785 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
786
Steven Thomasf43d13e2017-03-06 11:45:16 -0800787 compositor_surfaces_.reserve(2);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800788
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800789 constexpr int kFrameTimeBacklogMax = 2;
Steven Thomasf43d13e2017-03-06 11:45:16 -0800790 frame_time_backlog_.reserve(kFrameTimeBacklogMax);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800791
792 // Storage for retrieving fence info.
793 FenceInfoBuffer fence_info_buffer;
794
Steven Thomasf43d13e2017-03-06 11:45:16 -0800795 bool was_running = false;
796
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800797 while (1) {
798 ATRACE_NAME("HardwareComposer::PostThread");
799
Steven Thomas282a5ed2017-02-07 18:07:01 -0800800 {
Steven Thomasf43d13e2017-03-06 11:45:16 -0800801 std::unique_lock<std::mutex> lock(post_thread_mutex_);
802 while (!post_thread_enabled_ || post_thread_quit_requested_ ||
803 !PostThreadHasWork()) {
804 if (was_running) {
805 const char* pause_reason = "unknown";
806 if (!post_thread_enabled_)
807 pause_reason = "disabled";
808 else if (post_thread_quit_requested_)
809 pause_reason = "quit requested";
810 else if (!PostThreadHasWork())
811 pause_reason = "no work";
812 ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
813 OnPostThreadPaused();
814 was_running = false;
815 }
816 post_thread_running_ = false;
817 post_thread_cond_var_.notify_all();
818 if (post_thread_quit_requested_)
819 return;
820 post_thread_cond_var_.wait(lock);
Steven Thomas282a5ed2017-02-07 18:07:01 -0800821 }
Steven Thomasf43d13e2017-03-06 11:45:16 -0800822 post_thread_running_ = true;
823 }
824
825 if (!was_running) {
826 ALOGI("VrHwcPost thread resumed");
827 OnPostThreadResumed();
828 was_running = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800829 }
830
831 int64_t vsync_timestamp = 0;
832 {
833 std::array<char, 128> buf;
834 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
835 vsync_count_ + 1);
836 ATRACE_NAME(buf.data());
837
838 error = WaitForVSync(&vsync_timestamp);
839 ALOGE_IF(
840 error < 0,
841 "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
842 strerror(-error));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800843 // Don't bother processing this frame if a pause was requested
Steven Thomasf43d13e2017-03-06 11:45:16 -0800844 if (error == kPostThreadInterrupted)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800845 continue;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800846 }
847
848 ++vsync_count_;
849
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800850 if (pose_client_) {
851 // Signal the pose service with vsync info.
852 // Display timestamp is in the middle of scanout.
853 privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
854 vsync_timestamp + photon_offset_ns,
855 ns_per_frame, right_eye_photon_offset_ns);
856 }
857
Steven Thomasf43d13e2017-03-06 11:45:16 -0800858 bool layer_config_changed = UpdateLayerConfig();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800859
Steven Thomasf43d13e2017-03-06 11:45:16 -0800860 if (!was_running || layer_config_changed) {
861 frame_time_history_.ResetWithSeed(
862 GuessFrameTime(compositor_surfaces_.size()));
863 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800864 } else {
Steven Thomasf43d13e2017-03-06 11:45:16 -0800865 UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
866 &fence_info_buffer, &frame_time_history_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800867 }
868
869 // Get our current best estimate at how long the next frame will take to
870 // render, based on how long previous frames took to render. Use this
871 // estimate to decide when to wake up for EDS.
872 int64_t frame_time_estimate =
Steven Thomasf43d13e2017-03-06 11:45:16 -0800873 frame_time_history_.GetSampleCount() == 0
874 ? GuessFrameTime(compositor_surfaces_.size())
875 : frame_time_history_.GetAverage();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800876 frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
877 DebugHudData::data.hwc_latency = frame_time_estimate;
878
879 // Signal all of the vsync clients. Because absolute time is used for the
880 // wakeup time below, this can take a little time if necessary.
881 if (vsync_callback_)
882 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
883 vsync_count_);
884
885 {
886 // Sleep until async EDS wakeup time.
887 ATRACE_NAME("sleep");
888
889 int64_t display_time_est = vsync_timestamp + ns_per_frame;
890 int64_t now = GetSystemClockNs();
891 int64_t frame_finish_time_est = now + frame_time_estimate;
892 int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
893
894 ATRACE_INT64("sleep_time_ns", sleep_time_ns);
895 if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
896 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
897 ALOGE(
898 "HardwareComposer::PostThread: Missed frame schedule, drop "
899 "frame. Expected frame miss: %.1fms",
900 static_cast<double>(frame_finish_time_est - display_time_est) /
901 1000000);
902
903 // There are several reasons we might skip a frame, but one possibility
904 // is we mispredicted the frame time. Clear out the frame time history.
Steven Thomasf43d13e2017-03-06 11:45:16 -0800905 frame_time_history_.ResetWithSeed(
906 GuessFrameTime(compositor_surfaces_.size()));
907 frame_time_backlog_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800908 DebugHudData::data.hwc_frame_stats.SkipFrame();
909
910 continue;
911 } else {
912 // Make the transition more obvious in systrace when the frame skip
913 // happens above.
914 ATRACE_INT("frame_skip_count", 0);
915 }
916
917 if (sleep_time_ns > 0) {
918 error = SleepUntil(display_time_est - frame_time_estimate);
919 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
920 strerror(-error));
Steven Thomasf43d13e2017-03-06 11:45:16 -0800921 if (error == kPostThreadInterrupted)
922 continue;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800923 }
924 }
925
926 DebugHudData::data.hwc_frame_stats.AddFrame();
927
928 int64_t frame_start_time = GetSystemClockNs();
929
930 // Setup the output buffer for the compositor. This needs to happen before
931 // you draw with the compositor.
932 if (gpu_layer_ != nullptr) {
933 gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
934 }
935
936 // Call PostLayers now before performing the GL code for the compositor to
937 // avoid missing the deadline that can cause the lower-level hwc to get
938 // permanently backed up.
939 PostLayers(layer_config_changed);
940
Steven Thomasf43d13e2017-03-06 11:45:16 -0800941 PostCompositorBuffers();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800942
943 if (gpu_layer_ != nullptr) {
944 // Note, with scanline racing, this draw is timed along with the post
945 // layers to finish just in time.
946 LocalHandle frame_fence_fd;
947 compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
948 if (frame_fence_fd) {
Steven Thomasf43d13e2017-03-06 11:45:16 -0800949 LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800950 "Frame time backlog exceeds capacity");
Steven Thomasf43d13e2017-03-06 11:45:16 -0800951 frame_time_backlog_.push_back(
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800952 {frame_start_time, std::move(frame_fence_fd)});
953 }
954 } else if (!layer_config_changed) {
Steven Thomasf43d13e2017-03-06 11:45:16 -0800955 frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800956 }
957
958 HandlePendingScreenshots();
959 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800960}
961
Steven Thomasf43d13e2017-03-06 11:45:16 -0800962bool HardwareComposer::UpdateLayerConfig() {
963 std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
964 {
965 std::lock_guard<std::mutex> lock(post_thread_mutex_);
966 if (!active_surfaces_updated_)
967 return false;
968 old_display_surfaces = display_surfaces_;
969 display_surfaces_ = active_surfaces_;
970 active_surfaces_updated_ = false;
971 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800972
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800973 DebugHudData::data.ResetLayers();
974
Steven Thomasf43d13e2017-03-06 11:45:16 -0800975 // Figure out whether we need to update hardware layers. If this surface
976 // change does not add or remove hardware layers we can avoid display hiccups
977 // by gracefully updating only the GPU compositor layers.
978 int old_gpu_layer_count = 0;
979 int new_gpu_layer_count = 0;
980 bool hardware_layers_need_update = false;
981 // Look for new hardware layers and count new GPU layers.
982 for (const auto& surface : display_surfaces_) {
983 if (!(surface->flags() &
984 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
985 ++new_gpu_layer_count;
986 else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
987 surface) == old_display_surfaces.end())
988 // This is a new hardware layer, we need to update.
989 hardware_layers_need_update = true;
990 }
991 // Look for deleted hardware layers or compositor layers.
992 for (const auto& surface : old_display_surfaces) {
993 if (!(surface->flags() &
994 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
995 ++old_gpu_layer_count;
996 else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
997 surface) == display_surfaces_.end())
998 // This is a deleted hardware layer, we need to update.
999 hardware_layers_need_update = true;
1000 }
1001 // Check for compositor hardware layer transition.
1002 if ((!old_gpu_layer_count && new_gpu_layer_count) ||
1003 (old_gpu_layer_count && !new_gpu_layer_count))
1004 hardware_layers_need_update = true;
1005
1006 // Set the chosen layer order for all surfaces.
1007 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1008 display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
1009 }
1010
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001011 // Update compositor layers.
1012 {
1013 ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1014 compositor_.UpdateSurfaces(display_surfaces_);
Steven Thomasf43d13e2017-03-06 11:45:16 -08001015 compositor_surfaces_.clear();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001016 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1017 const auto& surface = display_surfaces_[i];
1018 if (!(surface->flags() &
1019 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
Steven Thomasf43d13e2017-03-06 11:45:16 -08001020 compositor_surfaces_.push_back(surface);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001021 }
1022 }
1023 }
1024
Steven Thomasf43d13e2017-03-06 11:45:16 -08001025 if (!hardware_layers_need_update)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001026 return true;
1027
1028 // Update hardware layers.
1029
1030 ATRACE_NAME("UpdateLayerConfig_HwLayers");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001031
1032 // Update the display layers in a non-destructive fashion.
1033
1034 // Create a map from surface id to hardware layer
1035 std::map<int, Layer*> display_surface_layers;
1036
1037 for (size_t i = 0; i < active_layer_count_; ++i) {
1038 auto layer = layers_[i];
1039 int surface_id = layer->GetSurfaceId();
1040
1041 auto found =
1042 std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1043 [surface_id](const auto& surface) {
1044 return surface->surface_id() == surface_id;
1045 });
1046
1047 if (found != display_surfaces_.end()) {
1048 display_surface_layers[surface_id] = layer;
1049 }
1050 }
1051
1052 bool has_gpu_layer = std::any_of(
1053 display_surfaces_.begin(), display_surfaces_.end(),
1054 [](const auto& surface) {
1055 return !(surface->flags() &
1056 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1057 });
1058
1059 if (!has_gpu_layer) {
1060 gpu_layer_ = nullptr;
1061 }
1062
1063 auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1064 int surface_id = layer->GetSurfaceId();
1065 if (surface_id >= 0) {
1066 return display_surface_layers.count(surface_id) > 0;
1067 } else {
1068 return has_gpu_layer;
1069 }
1070 };
1071
1072 // Compress the in-use layers to the top of the list
1073 auto part = std::partition(
1074 layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1075
1076 size_t new_active_layer_count = part - layers_.begin();
1077
1078 // Clear any unused layers
1079 for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1080 layers_[i]->Reset();
1081 }
1082
1083 active_layer_count_ = new_active_layer_count;
1084
1085 bool gpu_layer_applied = false;
1086
1087 // Create/update all of the hardware layers
1088 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1089 const auto& surface = display_surfaces_[i];
1090 bool is_hw_surface =
1091 surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1092 hwc2_blend_mode_t blending =
1093 i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1094
1095 DebugHudData::data.SetLayerInfo(
1096 i, surface->width(), surface->height(),
1097 !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1098
1099 if (!is_hw_surface && gpu_layer_applied) {
1100 continue;
1101 }
1102
1103 Layer* target_layer;
1104 bool existing_layer = false;
1105
1106 if (is_hw_surface) {
1107 auto it = display_surface_layers.find(surface->surface_id());
1108
1109 if (it != display_surface_layers.end()) {
1110 target_layer = it->second;
1111 existing_layer = true;
1112 }
1113 } else if (gpu_layer_ != nullptr) {
1114 target_layer = gpu_layer_;
1115 existing_layer = true;
1116 }
1117
1118 if (!existing_layer) {
1119 if (active_layer_count_ >= kMaxHardwareLayers) {
1120 ALOGI("HardwareComposer: More than %d hardware layers requested.",
1121 kMaxHardwareLayers);
1122 break;
1123 } else {
1124 target_layer = layers_[active_layer_count_];
1125 ++active_layer_count_;
1126 }
1127
1128 ALOGD_IF(TRACE,
1129 "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1130 "layer=%zd",
1131 surface->surface_id(), i);
1132
1133 if (is_hw_surface) {
1134 target_layer->Setup(surface, blending, display_transform_,
1135 HWC2_COMPOSITION_DEVICE, i);
1136 } else {
1137 gpu_layer_ = target_layer;
1138 target_layer->Setup(compositor_.GetBuffer(), blending,
1139 display_transform_, HWC2_COMPOSITION_DEVICE, i);
1140 }
1141 } else {
1142 ALOGD_IF(TRACE,
1143 "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1144 "-> layer=%zd",
1145 surface->surface_id(), i);
1146
1147 target_layer->SetBlending(blending);
1148 target_layer->SetZOrderIndex(i);
1149 target_layer->UpdateLayerSettings();
1150 }
1151
1152 gpu_layer_applied = !is_hw_surface;
1153 }
1154
1155 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1156 active_layer_count_);
1157
1158 return true;
1159}
1160
Steven Thomasf43d13e2017-03-06 11:45:16 -08001161void HardwareComposer::PostCompositorBuffers() {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001162 ATRACE_NAME("PostCompositorBuffers");
Steven Thomasf43d13e2017-03-06 11:45:16 -08001163 for (const auto& surface : compositor_surfaces_) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001164 compositor_.PostBuffer(surface);
1165 }
1166}
1167
1168void HardwareComposer::UpdateFrameTimeHistory(
1169 std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1170 FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1171 while (!backlog->empty()) {
1172 const auto& frame_time_record = backlog->front();
1173 int64_t end_time = 0;
1174 bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1175 fence_info_buffer, &end_time);
1176 if (frame_finished) {
1177 int64_t frame_duration = end_time - frame_time_record.start_time;
1178 history->AddSample(frame_duration);
1179 // Our backlog is tiny (2 elements), so erasing from the front is ok
1180 backlog->erase(backlog->begin());
1181 } else {
1182 break;
1183 }
1184 }
1185
1186 if (backlog->size() == static_cast<size_t>(backlog_max)) {
1187 // Yikes, something must've gone wrong if our oldest frame hasn't finished
1188 // yet. Give up on waiting for it.
1189 const auto& stale_frame_time_record = backlog->front();
1190 int64_t frame_duration =
1191 GetSystemClockNs() - stale_frame_time_record.start_time;
1192 backlog->erase(backlog->begin());
1193 history->AddSample(frame_duration);
1194 ALOGW("Frame didn't finish after %.1fms",
1195 static_cast<double>(frame_duration) / 1000000);
1196 }
1197}
1198
1199bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1200 FenceInfoBuffer* fence_info_buffer,
1201 int64_t* timestamp) {
1202 int result = -1;
1203 int sync_result = sync_wait(frame_fence_fd, 0);
1204 if (sync_result == 0) {
1205 result =
1206 GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1207 if (result < 0) {
1208 ALOGE("Failed getting signaled timestamp from fence");
1209 }
1210 } else if (errno != ETIME) {
1211 ALOGE("sync_wait on frame fence failed");
1212 }
1213 return result >= 0;
1214}
1215
1216void HardwareComposer::HandlePendingScreenshots() {
1217 // Take a screenshot of the requested layer, if available.
1218 // TODO(eieio): Look into using virtual displays to composite the layer stack
1219 // into a single output buffer that can be returned to the screenshot clients.
1220 if (active_layer_count_ > 0) {
1221 if (auto screenshot_service = ScreenshotService::GetInstance()) {
1222 if (screenshot_service->IsScreenshotRequestPending()) {
1223 ATRACE_NAME("screenshot");
1224 screenshot_service->TakeIfNeeded(layers_, compositor_);
1225 }
1226 } else {
1227 ALOGW(
1228 "HardwareComposer::HandlePendingScreenshots: Failed to get "
1229 "screenshot service!");
1230 }
1231 }
1232}
1233
1234void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1235 vsync_callback_ = callback;
1236}
1237
1238void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1239 hwc2_display_t /*display*/) {
1240 // TODO(eieio): implement invalidate callbacks.
1241}
1242
1243void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1244 hwc2_display_t /*display*/,
1245 int64_t /*timestamp*/) {
1246 ATRACE_NAME(__PRETTY_FUNCTION__);
1247 // Intentionally empty. HWC may require a callback to be set to enable vsync
1248 // signals. We bypass this callback thread by monitoring the vsync event
1249 // directly, but signals still need to be enabled.
1250}
1251
1252void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1253 hwc2_display_t /*display*/,
1254 hwc2_connection_t /*connected*/) {
1255 // TODO(eieio): implement display hotplug callbacks.
1256}
1257
Steven Thomas3cfac282017-02-06 12:29:30 -08001258void HardwareComposer::OnHardwareComposerRefresh() {
1259 // TODO(steventhomas): Handle refresh.
1260}
1261
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001262void HardwareComposer::SetBacklightBrightness(int brightness) {
1263 if (backlight_brightness_fd_) {
1264 std::array<char, 32> text;
1265 const int length = snprintf(text.data(), text.size(), "%d", brightness);
1266 write(backlight_brightness_fd_.Get(), text.data(), length);
1267 }
1268}
1269
1270Layer::Layer()
1271 : hwc2_hidl_(nullptr),
1272 surface_index_(-1),
1273 hardware_composer_layer_(0),
1274 display_metrics_(nullptr),
1275 blending_(HWC2_BLEND_MODE_NONE),
1276 transform_(HWC_TRANSFORM_NONE),
1277 composition_type_(HWC2_COMPOSITION_DEVICE),
1278 surface_rect_functions_applied_(false) {}
1279
1280void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1281 hwc2_hidl_ = hwc2_hidl;
1282 display_metrics_ = metrics;
1283}
1284
1285void Layer::Reset() {
1286 const int ret = acquired_buffer_.Release(std::move(release_fence_));
1287 ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1288 strerror(-ret));
1289
1290 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1291 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1292 hardware_composer_layer_ = 0;
1293 }
1294
1295 surface_index_ = static_cast<size_t>(-1);
1296 blending_ = HWC2_BLEND_MODE_NONE;
1297 transform_ = HWC_TRANSFORM_NONE;
1298 composition_type_ = HWC2_COMPOSITION_DEVICE;
1299 direct_buffer_ = nullptr;
1300 surface_ = nullptr;
1301 acquire_fence_fd_.Close();
1302 surface_rect_functions_applied_ = false;
1303}
1304
1305void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1306 hwc2_blend_mode_t blending, hwc_transform_t transform,
1307 hwc2_composition_t composition_type, size_t index) {
1308 Reset();
1309 surface_index_ = index;
1310 surface_ = surface;
1311 blending_ = blending;
1312 transform_ = transform;
1313 composition_type_ = composition_type;
1314 CommonLayerSetup();
1315}
1316
1317void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1318 hwc2_blend_mode_t blending, hwc_transform_t transform,
1319 hwc2_composition_t composition_type, size_t z_order) {
1320 Reset();
1321 surface_index_ = z_order;
1322 direct_buffer_ = buffer;
1323 blending_ = blending;
1324 transform_ = transform;
1325 composition_type_ = composition_type;
1326 CommonLayerSetup();
1327}
1328
1329void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1330 direct_buffer_ = buffer;
1331}
1332
1333void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1334
1335void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1336
1337IonBuffer* Layer::GetBuffer() {
1338 if (direct_buffer_)
1339 return direct_buffer_.get();
1340 else if (acquired_buffer_.IsAvailable())
1341 return acquired_buffer_.buffer()->buffer();
1342 else
1343 return nullptr;
1344}
1345
1346void Layer::UpdateLayerSettings() {
1347 if (!IsLayerSetup()) {
1348 ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1349 return;
1350 }
1351
1352 int32_t ret = HWC2_ERROR_NONE;
1353
1354 hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1355
1356 ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1357 display, hardware_composer_layer_,
1358 (Hwc2::IComposerClient::Composition)composition_type_);
1359 ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1360 ret);
1361 // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1362 // hardware_composer_layer_,
1363 // (Hwc2::IComposerClient::Transform)
1364 // transform_);
1365 // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1366
1367 // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1368 // hardware_composer_device_, display, hardware_composer_layer_,
1369 // blending_);
1370 ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1371 display, hardware_composer_layer_,
1372 (Hwc2::IComposerClient::BlendMode)blending_);
1373 ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1374
1375 Hwc2::IComposerClient::Rect display_frame;
1376 display_frame.left = 0;
1377 display_frame.top = 0;
1378 display_frame.right = display_metrics_->width;
1379 display_frame.bottom = display_metrics_->height;
1380 ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1381 display, hardware_composer_layer_, display_frame);
1382 ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1383 ret);
1384
1385 std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1386 visible_region[0] = display_frame;
1387 ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1388 display, hardware_composer_layer_, visible_region);
1389 ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1390 ret);
1391
1392 ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1393 hardware_composer_layer_, 1.0f);
1394 ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1395
1396 ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1397 surface_index_);
1398 ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1399}
1400
1401void Layer::CommonLayerSetup() {
1402 int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1403 &hardware_composer_layer_);
1404
1405 ALOGE_IF(ret,
1406 "HardwareComposer: Failed to create layer on primary display : %d",
1407 ret);
1408
1409 UpdateLayerSettings();
1410}
1411
1412void Layer::Prepare() {
1413 int right, bottom;
1414 buffer_handle_t handle;
1415
1416 if (surface_) {
1417 // Only update the acquired buffer when one is either available or this is
1418 // the first time through.
1419 if (surface_->IsBufferAvailable()) {
1420 // If we previously set this to a solid color layer to stall for time,
1421 // revert it to a device layer.
1422 if (acquired_buffer_.IsEmpty() &&
1423 composition_type_ != HWC2_COMPOSITION_DEVICE) {
1424 composition_type_ = HWC2_COMPOSITION_DEVICE;
1425 hwc2_hidl_->setLayerCompositionType(
1426 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1427 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1428 }
1429
1430 DebugHudData::data.AddLayerFrame(surface_index_);
1431 acquired_buffer_.Release(std::move(release_fence_));
1432 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1433
1434 // Basic latency stopgap for when the application misses a frame:
1435 // If the application recovers on the 2nd or 3rd (etc) frame after
1436 // missing, this code will skip a frame to catch up by checking if
1437 // the next frame is also available.
1438 if (surface_->IsBufferAvailable()) {
1439 DebugHudData::data.SkipLayerFrame(surface_index_);
1440 ATRACE_NAME("DropToCatchUp");
1441 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1442 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1443 }
1444 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1445 } else if (acquired_buffer_.IsEmpty()) {
1446 // While we are waiting for a buffer, set this to be an empty layer
1447 if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1448 composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1449 hwc2_hidl_->setLayerCompositionType(
1450 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1451 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1452
1453 Hwc2::IComposerClient::Color layer_color = {
1454 0, 0, 0, 0,
1455 };
1456 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1457 layer_color);
1458 }
1459 return;
1460 }
1461 right = acquired_buffer_.buffer()->width();
1462 bottom = acquired_buffer_.buffer()->height();
1463 handle = acquired_buffer_.buffer()->native_handle();
1464 acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1465 } else {
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -08001466 // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
1467 // mechanism to accept distorted layers from VrCore.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001468 right = direct_buffer_->width();
1469 bottom = direct_buffer_->height();
1470 handle = direct_buffer_->handle();
1471 acquire_fence_fd_.Close();
1472 }
1473
1474 int32_t ret = HWC2_ERROR_NONE;
1475
1476 if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1477 ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001478 hardware_composer_layer_, 0,
1479 handle,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001480 acquire_fence_fd_.Get());
1481
1482 ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1483 }
1484
1485 if (!surface_rect_functions_applied_) {
1486 Hwc2::IComposerClient::FRect crop_rect = {
1487 0, 0, static_cast<float>(right), static_cast<float>(bottom),
1488 };
1489 hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1490 hardware_composer_layer_, crop_rect);
1491
1492 ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1493 ret);
1494
1495// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1496// it must/cannot be called?
1497#ifdef QCOM_BSP
1498 hwc_rect_t damage_rect = {
1499 0, 0, right, bottom,
1500 };
1501 hwc_region_t damage = {
1502 1, &damage_rect,
1503 };
1504 // ret = hwc2_funcs_->set_layer_surface_damage(
1505 // hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1506 // hardware_composer_layer_, damage);
1507 // uses a std::vector as the listing
1508 // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1509 // hardware_composer_layer_, vector here);
1510
1511 ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1512 ret);
1513#endif
1514
1515 surface_rect_functions_applied_ = true;
1516 }
1517}
1518
1519void Layer::Finish(int release_fence_fd) {
1520 release_fence_.Reset(release_fence_fd);
1521}
1522
1523void Layer::Drop() { acquire_fence_fd_.Close(); }
1524
1525} // namespace dvr
1526} // namespace android