blob: e6ed66589f8d360a6316cb1003e0dc7c2875d49e [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)
103 : hwc2_hidl_(hwc2_hidl),
104 display_transform_(HWC_TRANSFORM_NONE),
105 display_surfaces_updated_(false),
106 hardware_layers_need_update_(false),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800107 active_layer_count_(0),
108 gpu_layer_(nullptr),
Steven Thomas282a5ed2017-02-07 18:07:01 -0800109 post_thread_state_(PostThreadState::kPaused),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800110 terminate_post_thread_event_fd_(-1),
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800111 backlight_brightness_fd_(-1),
112 primary_display_vsync_event_fd_(-1),
113 primary_display_wait_pp_fd_(-1),
114 vsync_sleep_timer_fd_(-1),
115 last_vsync_timestamp_(0),
116 vsync_count_(0),
117 frame_skip_count_(0),
118 pose_client_(nullptr) {
119 std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(),
120 [](auto& layer) { return &layer; });
121
122 callbacks_ = new ComposerCallback;
123}
124
125HardwareComposer::~HardwareComposer(void) {
Steven Thomas282a5ed2017-02-07 18:07:01 -0800126 Suspend();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800127}
128
129bool HardwareComposer::Resume() {
Steven Thomas282a5ed2017-02-07 18:07:01 -0800130 std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
131 if (post_thread_state_ == PostThreadState::kRunning) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800132 return false;
133 }
134
Steven Thomas282a5ed2017-02-07 18:07:01 -0800135 std::lock_guard<std::mutex> layer_lock(layer_mutex_);
136
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800137 int32_t ret = HWC2_ERROR_NONE;
138
139 static const uint32_t attributes[] = {
140 HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_VSYNC_PERIOD,
141 HWC_DISPLAY_DPI_X, HWC_DISPLAY_DPI_Y, HWC_DISPLAY_NO_ATTRIBUTE,
142 };
143
144 std::vector<Hwc2::Config> configs;
145 ret = (int32_t)hwc2_hidl_->getDisplayConfigs(HWC_DISPLAY_PRIMARY, &configs);
146
147 if (ret != HWC2_ERROR_NONE) {
148 ALOGE("HardwareComposer: Failed to get display configs");
149 return false;
150 }
151
152 uint32_t num_configs = configs.size();
153
154 for (size_t i = 0; i < num_configs; i++) {
155 ALOGI("HardwareComposer: cfg[%zd/%zd] = 0x%08x", i, num_configs,
156 configs[i]);
157
158 ret = GetDisplayMetrics(HWC_DISPLAY_PRIMARY, configs[i],
159 &native_display_metrics_);
160
161 if (ret != HWC2_ERROR_NONE) {
162 ALOGE("HardwareComposer: Failed to get display attributes %d", ret);
163 continue;
164 } else {
165 ret =
166 (int32_t)hwc2_hidl_->setActiveConfig(HWC_DISPLAY_PRIMARY, configs[i]);
167
168 if (ret != HWC2_ERROR_NONE) {
169 ALOGE("HardwareComposer: Failed to set display configuration; ret=%d",
170 ret);
171 continue;
172 }
173
174 break;
175 }
176 }
177
178 if (ret != HWC2_ERROR_NONE) {
179 ALOGE("HardwareComposer: Could not set a valid display configuration.");
180 return false;
181 }
182
183 // Set the display metrics but never use rotation to avoid the long latency of
184 // rotation processing in hwc.
185 display_transform_ = HWC_TRANSFORM_NONE;
186 display_metrics_ = native_display_metrics_;
187
188 ALOGI(
189 "HardwareComposer: primary display attributes: width=%d height=%d "
190 "vsync_period_ns=%d DPI=%dx%d",
191 native_display_metrics_.width, native_display_metrics_.height,
192 native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
193 native_display_metrics_.dpi.y);
194
195 // Always turn off vsync when we start.
196 EnableVsync(false);
197
198 constexpr int format = HAL_PIXEL_FORMAT_RGBA_8888;
199 constexpr int usage =
200 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER;
201
202 framebuffer_target_ = std::make_shared<IonBuffer>(
203 native_display_metrics_.width, native_display_metrics_.height, format,
204 usage);
205
206 // Associate each Layer instance with a hardware composer layer.
207 for (auto layer : layers_) {
208 layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
209 }
210
Hendrik Wagenaarea572422017-02-02 10:00:48 -0800211#if ENABLE_BACKLIGHT_BRIGHTNESS
212 // TODO(hendrikw): This isn't required at the moment. It's possible that there
213 // is another method to access this when needed.
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800214 // Open the backlight brightness control sysfs node.
215 backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
216 ALOGW_IF(!backlight_brightness_fd_,
217 "HardwareComposer: Failed to open backlight brightness control: %s",
218 strerror(errno));
Hendrik Wagenaarea572422017-02-02 10:00:48 -0800219#endif // ENABLE_BACKLIGHT_BRIGHTNESS
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800220
221 // Open the vsync event node for the primary display.
222 // TODO(eieio): Move this into a platform-specific class.
223 primary_display_vsync_event_fd_ =
224 LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
225 ALOGE_IF(!primary_display_vsync_event_fd_,
226 "HardwareComposer: Failed to open vsync event node for primary "
227 "display: %s",
228 strerror(errno));
229
230 // Open the wait pingpong status node for the primary display.
231 // TODO(eieio): Move this into a platform-specific class.
232 primary_display_wait_pp_fd_ =
233 LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
234 ALOGE_IF(
235 !primary_display_wait_pp_fd_,
236 "HardwareComposer: Failed to open wait_pp node for primary display: %s",
237 strerror(errno));
238
239 // Create a timerfd based on CLOCK_MONOTINIC.
240 vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
241 LOG_ALWAYS_FATAL_IF(
242 !vsync_sleep_timer_fd_,
243 "HardwareComposer: Failed to create vsync sleep timerfd: %s",
244 strerror(errno));
245
246 // Connect to pose service.
247 pose_client_ = dvrPoseCreate();
248 ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
249
Steven Thomas282a5ed2017-02-07 18:07:01 -0800250 terminate_post_thread_event_fd_.Reset(
251 eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800252 LOG_ALWAYS_FATAL_IF(
253 !terminate_post_thread_event_fd_,
254 "HardwareComposer: Failed to create terminate PostThread event fd : %s",
255 strerror(errno));
256
Steven Thomas282a5ed2017-02-07 18:07:01 -0800257 post_thread_state_ = PostThreadState::kRunning;
258 post_thread_state_cond_var_.notify_all();
259
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800260 // If get_id() is the default thread::id object, it has not been created yet
261 if (post_thread_.get_id() == std::thread::id()) {
262 post_thread_ = std::thread(&HardwareComposer::PostThread, this);
263 } else {
264 UpdateDisplayState();
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800265 }
266
267 return true;
268}
269
270bool HardwareComposer::Suspend() {
Steven Thomas282a5ed2017-02-07 18:07:01 -0800271 std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
272 if (post_thread_state_ == PostThreadState::kPaused) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800273 return false;
274 }
275
Steven Thomas282a5ed2017-02-07 18:07:01 -0800276 post_thread_state_ = PostThreadState::kPauseRequested;
277
278 int error = eventfd_write(terminate_post_thread_event_fd_.Get(), 1);
279 ALOGE_IF(error,
280 "HardwareComposer::Suspend: could not write post "
281 "thread termination event fd : %d",
282 error);
283
284 post_thread_state_cond_var_.wait(
285 post_thread_lock,
286 [this] { return post_thread_state_ == PostThreadState::kPaused; });
287 terminate_post_thread_event_fd_.Close();
288
289 // Wait for any pending layer operations to finish
290 std::lock_guard<std::mutex> layer_lock(layer_mutex_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800291
292 EnableVsync(false);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800293
294 backlight_brightness_fd_.Close();
295 primary_display_vsync_event_fd_.Close();
296 primary_display_wait_pp_fd_.Close();
297 vsync_sleep_timer_fd_.Close();
298 retire_fence_fds_.clear();
299 gpu_layer_ = nullptr;
300
301 // We have to destroy the layers before we close the hwc device
302 for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
303 layers_[i]->Reset();
304 }
305
306 active_layer_count_ = 0;
307
308 framebuffer_target_.reset();
309
310 //hwc2_hidl_.reset();
311
312 if (pose_client_)
313 dvrPoseDestroy(pose_client_);
314
315 return true;
316}
317
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800318DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
319 vec2i screen_size(display_metrics_.width, display_metrics_.height);
320 DisplayOrientation orientation =
321 (display_metrics_.width > display_metrics_.height
322 ? DisplayOrientation::kLandscape
323 : DisplayOrientation::kPortrait);
324 float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
325 float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
326 float meters_per_pixel_x = kMetersPerInch / dpi_x;
327 float meters_per_pixel_y = kMetersPerInch / dpi_y;
328 vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
329 double frame_duration_s =
330 static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
331 // TODO(hendrikw): Hard coding to 3mm. The Pixel is actually 4mm, but it
332 // seems that their tray to lens distance is wrong too, which
333 // offsets this, at least for the pixel.
334 float border_size = 0.003f;
335 return DisplayMetrics(screen_size, meters_per_pixel, border_size,
336 static_cast<float>(frame_duration_s), orientation);
337}
338
339int32_t HardwareComposer::Validate(hwc2_display_t display) {
340 uint32_t num_types;
341 uint32_t num_requests;
342 int32_t error =
343 (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
344
345 if (error == HWC2_ERROR_HAS_CHANGES) {
346 // TODO(skiazyk): We might need to inspect the requested changes first, but
347 // so far it seems like we shouldn't ever hit a bad state.
348 // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
349 // display);
350 error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
351 }
352
353 return error;
354}
355
356int32_t HardwareComposer::EnableVsync(bool enabled) {
357 return (int32_t)hwc2_hidl_->setVsyncEnabled(
358 HWC_DISPLAY_PRIMARY,
359 (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
360 : HWC2_VSYNC_DISABLE));
361}
362
363int32_t HardwareComposer::Present(hwc2_display_t display) {
364 int32_t present_fence;
365 int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
366
367 // According to the documentation, this fence is signaled at the time of
368 // vsync/DMA for physical displays.
369 if (error == HWC2_ERROR_NONE) {
370 ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
371 retire_fence_fds_.emplace_back(present_fence);
372 } else {
373 ATRACE_INT("HardwareComposer: PresentResult", error);
374 }
375
376 return error;
377}
378
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800379int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
380 hwc2_config_t config,
381 hwc2_attribute_t attribute,
382 int32_t* out_value) const {
383 return (int32_t)hwc2_hidl_->getDisplayAttribute(
384 display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
385}
386
387int32_t HardwareComposer::GetDisplayMetrics(
388 hwc2_display_t display, hwc2_config_t config,
389 HWCDisplayMetrics* out_metrics) const {
390 int32_t ret = HWC2_ERROR_NONE;
391
392 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
393 &out_metrics->width);
394 if (ret != HWC2_ERROR_NONE) {
395 ALOGE("HardwareComposer: Failed to get display width");
396 return ret;
397 }
398
399 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
400 &out_metrics->height);
401 if (ret != HWC2_ERROR_NONE) {
402 ALOGE("HardwareComposer: Failed to get display height");
403 return ret;
404 }
405
406 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
407 &out_metrics->vsync_period_ns);
408 if (ret != HWC2_ERROR_NONE) {
409 ALOGE("HardwareComposer: Failed to get display height");
410 return ret;
411 }
412
413 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
414 &out_metrics->dpi.x);
415 if (ret != HWC2_ERROR_NONE) {
416 ALOGE("HardwareComposer: Failed to get display DPI X");
417 return ret;
418 }
419
420 ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
421 &out_metrics->dpi.y);
422 if (ret != HWC2_ERROR_NONE) {
423 ALOGE("HardwareComposer: Failed to get display DPI Y");
424 return ret;
425 }
426
427 return HWC2_ERROR_NONE;
428}
429
430void HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
431 std::string debug_str = hwc2_hidl_->dumpDebugInfo();
432 ALOGI("%s", debug_str.c_str());
433
434 if (buffer == nullptr) {
435 *out_size = debug_str.size();
436 } else {
437 std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
438 }
439}
440
441// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
442// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
443// there.
444void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
445 ATRACE_NAME("HardwareComposer::PostLayers");
446
447 // Setup the hardware composer layers with current buffers.
448 for (size_t i = 0; i < active_layer_count_; i++) {
449 layers_[i]->Prepare();
450 }
451
452 // Now that we have taken in a frame from the application, we have a chance
453 // to drop the frame before passing the frame along to HWC.
454 // If the display driver has become backed up, we detect it here and then
455 // react by skipping this frame to catch up latency.
456 while (!retire_fence_fds_.empty() &&
457 (!retire_fence_fds_.front() ||
458 sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
459 // There are only 2 fences in here, no performance problem to shift the
460 // array of ints.
461 retire_fence_fds_.erase(retire_fence_fds_.begin());
462 }
463
464 const bool is_frame_pending = IsFramePendingInDriver();
465 const bool is_fence_pending =
466 retire_fence_fds_.size() > kAllowedPendingFenceCount;
467
468 if (is_fence_pending || is_frame_pending) {
469 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
470
471 ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
472 ALOGW_IF(is_fence_pending,
473 "Warning: dropping a frame to catch up with HWC (pending = %zd)",
474 retire_fence_fds_.size());
475
476 for (size_t i = 0; i < active_layer_count_; i++) {
477 layers_[i]->Drop();
478 }
479 return;
480 } else {
481 // Make the transition more obvious in systrace when the frame skip happens
482 // above.
483 ATRACE_INT("frame_skip_count", 0);
484 }
485
486#if TRACE
487 for (size_t i = 0; i < active_layer_count_; i++)
488 ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
489 layers_[i]->GetCompositionType());
490#endif
491
492 int32_t ret = HWC2_ERROR_NONE;
493
494 std::vector<Hwc2::IComposerClient::Rect> full_region(1);
495 full_region[0].left = 0;
496 full_region[0].top = 0;
497 full_region[0].right = framebuffer_target_->width();
498 full_region[0].bottom = framebuffer_target_->height();
499
500 ALOGE_IF(ret, "Error setting client target : %d", ret);
501
502 ret = Validate(HWC_DISPLAY_PRIMARY);
503 if (ret) {
504 ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
505 return;
506 }
507
508 ret = Present(HWC_DISPLAY_PRIMARY);
509 if (ret) {
510 ALOGE("HardwareComposer::Present failed; ret=%d", ret);
511 return;
512 }
513
514 std::vector<Hwc2::Layer> out_layers;
515 std::vector<int> out_fences;
516 ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
517 &out_fences);
518 uint32_t num_elements = out_layers.size();
519
520 ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
521
522 // Perform post-frame bookkeeping. Unused layers are a no-op.
523 for (size_t i = 0; i < num_elements; ++i) {
524 for (size_t j = 0; j < active_layer_count_; ++j) {
525 if (layers_[j]->GetLayerHandle() == out_layers[i]) {
526 layers_[j]->Finish(out_fences[i]);
527 }
528 }
529 }
530}
531
532// TODO(skiazyk): This is a work-around for the fact that we currently do not
533// handle the case when new surfaces are introduced when displayd is not
534// in an active state. A proper-solution will require re-structuring
535// displayd a little, but hopefully this is sufficient for now.
536// For example, could this be handled in |UpdateLayerSettings| instead?
537void HardwareComposer::UpdateDisplayState() {
538 const bool has_display_surfaces = display_surfaces_.size() > 0;
539
540 if (has_display_surfaces) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800541 EnableVsync(true);
542 }
Jiwen 'Steve' Cai105036f2017-02-07 16:39:38 -0800543
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800544 // TODO(skiazyk): We need to do something about accessing this directly,
545 // supposedly there is a backlight service on the way.
546 SetBacklightBrightness(255);
547
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800548 // Trigger target-specific performance mode change.
Jiwen 'Steve' Cai105036f2017-02-07 16:39:38 -0800549 property_set(kDvrPerformanceProperty, has_display_surfaces ? "performance" : "idle");
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800550}
551
552int HardwareComposer::SetDisplaySurfaces(
553 std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
Steven Thomas282a5ed2017-02-07 18:07:01 -0800554 // The double lock is necessary because we access both the display surfaces
555 // and post_thread_state_.
556 std::lock_guard<std::mutex> post_thread_state_lock(post_thread_state_mutex_);
557 std::lock_guard<std::mutex> layer_lock(layer_mutex_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800558
559 ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
560 surfaces.size());
561
562 // Figure out whether we need to update hardware layers. If this surface
563 // change does not add or remove hardware layers we can avoid display hiccups
564 // by gracefully updating only the GPU compositor layers.
565 // hardware_layers_need_update_ is reset to false by the Post thread.
566 int old_gpu_layer_count = 0;
567 int new_gpu_layer_count = 0;
568 // Look for new hardware layers and count new GPU layers.
569 for (const auto& surface : surfaces) {
570 if (!(surface->flags() &
571 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
572 ++new_gpu_layer_count;
573 else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
574 surface) == display_surfaces_.end())
575 // This is a new hardware layer, we need to update.
576 hardware_layers_need_update_ = true;
577 }
578 // Look for deleted hardware layers or compositor layers.
579 for (const auto& surface : display_surfaces_) {
580 if (!(surface->flags() &
581 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
582 ++old_gpu_layer_count;
583 else if (std::find(surfaces.begin(), surfaces.end(), surface) ==
584 surfaces.end())
585 // This is a deleted hardware layer, we need to update.
586 hardware_layers_need_update_ = true;
587 }
588 // Check for compositor hardware layer transition.
589 if ((!old_gpu_layer_count && new_gpu_layer_count) ||
590 (old_gpu_layer_count && !new_gpu_layer_count))
591 hardware_layers_need_update_ = true;
592
593 display_surfaces_ = std::move(surfaces);
594 display_surfaces_updated_ = true;
595
596 // Set the chosen layer order for all surfaces.
597 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
598 display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
599 }
600
601 // TODO(skiazyk): fix this so that it is handled seamlessly with dormant/non-
602 // dormant state.
Steven Thomas282a5ed2017-02-07 18:07:01 -0800603 if (post_thread_state_ == PostThreadState::kRunning) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800604 UpdateDisplayState();
605 }
606
607 return 0;
608}
609
610// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
611// (the value of the state) on success or a negative error otherwise.
612// TODO(eieio): This is pretty driver specific, this should be moved to a
613// separate class eventually.
614int HardwareComposer::ReadWaitPPState() {
615 // Gracefully handle when the kernel does not support this feature.
616 if (!primary_display_wait_pp_fd_)
617 return 0;
618
619 const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
620 int ret, error;
621
622 ret = lseek(wait_pp_fd, 0, SEEK_SET);
623 if (ret < 0) {
624 error = errno;
625 ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
626 strerror(error));
627 return -error;
628 }
629
630 char data = -1;
631 ret = read(wait_pp_fd, &data, sizeof(data));
632 if (ret < 0) {
633 error = errno;
634 ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
635 strerror(error));
636 return -error;
637 }
638
639 switch (data) {
640 case '0':
641 return 0;
642 case '1':
643 return 1;
644 default:
645 ALOGE(
646 "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
647 data);
648 return -EINVAL;
649 }
650}
651
652// Reads the timestamp of the last vsync from the display driver.
653// TODO(eieio): This is pretty driver specific, this should be moved to a
654// separate class eventually.
655int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
656 const int event_fd = primary_display_vsync_event_fd_.Get();
657 int ret, error;
658
659 // The driver returns data in the form "VSYNC=<timestamp ns>".
660 std::array<char, 32> data;
661 data.fill('\0');
662
663 // Seek back to the beginning of the event file.
664 ret = lseek(event_fd, 0, SEEK_SET);
665 if (ret < 0) {
666 error = errno;
667 ALOGE(
668 "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
669 "%s",
670 strerror(error));
671 return -error;
672 }
673
674 // Read the vsync event timestamp.
675 ret = read(event_fd, data.data(), data.size());
676 if (ret < 0) {
677 error = errno;
678 ALOGE_IF(
679 error != EAGAIN,
680 "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
681 "%s",
682 strerror(error));
683 return -error;
684 }
685
686 ret = sscanf(data.data(), "VSYNC=%" PRIu64,
687 reinterpret_cast<uint64_t*>(timestamp));
688 if (ret < 0) {
689 error = errno;
690 ALOGE(
691 "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
692 "%s",
693 strerror(error));
694 return -error;
695 }
696
697 return 0;
698}
699
700// Blocks until the next vsync event is signaled by the display driver.
701// TODO(eieio): This is pretty driver specific, this should be moved to a
702// separate class eventually.
Steven Thomas282a5ed2017-02-07 18:07:01 -0800703int HardwareComposer::BlockUntilVSync(/*out*/ bool* suspend_requested) {
704 *suspend_requested = false;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800705 const int event_fd = primary_display_vsync_event_fd_.Get();
706 pollfd pfd[2] = {
707 {
708 .fd = event_fd, .events = POLLPRI, .revents = 0,
709 },
710 // This extra event fd is to ensure that we can break out of this loop to
711 // pause the thread even when vsync is disabled, and thus no events on the
712 // vsync fd are being generated.
713 {
714 .fd = terminate_post_thread_event_fd_.Get(),
715 .events = POLLPRI | POLLIN,
716 .revents = 0,
717 },
718 };
719 int ret, error;
720 do {
721 ret = poll(pfd, 2, -1);
722 error = errno;
723 ALOGW_IF(ret < 0,
724 "HardwareComposer::BlockUntilVSync: Error while waiting for vsync "
725 "event: %s (%d)",
726 strerror(error), error);
727 } while (ret < 0 && error == EINTR);
728
Steven Thomas282a5ed2017-02-07 18:07:01 -0800729 if (ret >= 0 && pfd[1].revents != 0)
730 *suspend_requested = true;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800731 return ret < 0 ? -error : 0;
732}
733
734// Waits for the next vsync and returns the timestamp of the vsync event. If
735// vsync already passed since the last call, returns the latest vsync timestamp
736// instead of blocking. This method updates the last_vsync_timeout_ in the
737// process.
738//
739// TODO(eieio): This is pretty driver specific, this should be moved to a
740// separate class eventually.
741int HardwareComposer::WaitForVSync(int64_t* timestamp) {
742 int error;
743
744 // Get the current timestamp and decide what to do.
745 while (true) {
746 int64_t current_vsync_timestamp;
747 error = ReadVSyncTimestamp(&current_vsync_timestamp);
748 if (error < 0 && error != -EAGAIN)
749 return error;
750
751 if (error == -EAGAIN) {
752 // Vsync was turned off, wait for the next vsync event.
Steven Thomas282a5ed2017-02-07 18:07:01 -0800753 bool suspend_requested = false;
754 error = BlockUntilVSync(&suspend_requested);
755 if (error < 0 || suspend_requested)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800756 return error;
757
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800758 // Try again to get the timestamp for this new vsync interval.
759 continue;
760 }
761
762 // Check that we advanced to a later vsync interval.
763 if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
764 *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
765 return 0;
766 }
767
768 // See how close we are to the next expected vsync. If we're within 1ms,
769 // sleep for 1ms and try again.
770 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
771 const int64_t threshold_ns = 1000000;
772
773 const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
774 const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
775
776 if (distance_to_vsync_est > threshold_ns) {
777 // Wait for vsync event notification.
Steven Thomas282a5ed2017-02-07 18:07:01 -0800778 bool suspend_requested = false;
779 error = BlockUntilVSync(&suspend_requested);
780 if (error < 0 || suspend_requested)
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800781 return error;
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800782 } else {
783 // Sleep for a short time before retrying.
784 std::this_thread::sleep_for(std::chrono::milliseconds(1));
785 }
786 }
787}
788
789int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
790 const int timer_fd = vsync_sleep_timer_fd_.Get();
791 const itimerspec wakeup_itimerspec = {
792 .it_interval = {.tv_sec = 0, .tv_nsec = 0},
793 .it_value = NsToTimespec(wakeup_timestamp),
794 };
795 int ret =
796 timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
797 int error = errno;
798 if (ret < 0) {
799 ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
800 strerror(error));
801 return -error;
802 }
803
804 // Wait for the timer by reading the expiration count.
805 uint64_t expiration_count;
806 ret = read(timer_fd, &expiration_count, sizeof(expiration_count));
807 if (ret < 0) {
808 ALOGE("HardwareComposer::SleepUntil: Failed to wait for timerfd: %s",
809 strerror(error));
810 return -error;
811 }
812
813 return 0;
814}
815
816void HardwareComposer::PostThread() {
817 // NOLINTNEXTLINE(runtime/int)
818 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("PostThread"), 0, 0, 0);
819
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800820 // Set the scheduler to SCHED_FIFO with high priority.
821 int error = dvrSetSchedulerClass(0, "graphics:high");
822 LOG_ALWAYS_FATAL_IF(
823 error < 0,
824 "HardwareComposer::PostThread: Failed to set scheduler class: %s",
825 strerror(-error));
826 error = dvrSetCpuPartition(0, "/system/performance");
827 LOG_ALWAYS_FATAL_IF(
828 error < 0,
829 "HardwareComposer::PostThread: Failed to set cpu partition: %s",
830 strerror(-error));
831
832 // Force the layers to be setup at least once.
833 display_surfaces_updated_ = true;
834
835 // Initialize the GPU compositor.
836 LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
837 "Failed to initialize the compositor");
838
839 const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
840 const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
841
842 // TODO(jbates) Query vblank time from device, when such an API is available.
843 // This value (6.3%) was measured on A00 in low persistence mode.
844 int64_t vblank_ns = ns_per_frame * 63 / 1000;
845 int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
846
847 // Check property for overriding right eye offset value.
848 right_eye_photon_offset_ns =
849 property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
850
851 // The list of surfaces the compositor should attempt to render. This is set
852 // at the start of each frame.
853 std::vector<std::shared_ptr<DisplaySurface>> compositor_surfaces;
854 compositor_surfaces.reserve(2);
855
856 // Our history of frame times. This is used to get a better estimate of how
857 // long the next frame will take, to set a schedule for EDS.
858 FrameTimeHistory frame_time_history;
859
860 // The backlog is used to allow us to start rendering the next frame before
861 // the previous frame has finished, and still get an accurate measurement of
862 // frame duration.
863 std::vector<FrameTimeMeasurementRecord> frame_time_backlog;
864 constexpr int kFrameTimeBacklogMax = 2;
865 frame_time_backlog.reserve(kFrameTimeBacklogMax);
866
867 // Storage for retrieving fence info.
868 FenceInfoBuffer fence_info_buffer;
869
870 while (1) {
871 ATRACE_NAME("HardwareComposer::PostThread");
872
Steven Thomas282a5ed2017-02-07 18:07:01 -0800873 {
874 std::unique_lock<std::mutex> post_thread_lock(post_thread_state_mutex_);
875 if (post_thread_state_ == PostThreadState::kPauseRequested) {
876 ALOGI("HardwareComposer::PostThread: Post thread pause requested.");
877 post_thread_state_ = PostThreadState::kPaused;
878 post_thread_state_cond_var_.notify_all();
879 post_thread_state_cond_var_.wait(
880 post_thread_lock,
881 [this] { return post_thread_state_ == PostThreadState::kRunning; });
882 // The layers will need to be updated since they were deleted previously
883 display_surfaces_updated_ = true;
884 hardware_layers_need_update_ = true;
885 }
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800886 }
887
888 int64_t vsync_timestamp = 0;
889 {
890 std::array<char, 128> buf;
891 snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
892 vsync_count_ + 1);
893 ATRACE_NAME(buf.data());
894
895 error = WaitForVSync(&vsync_timestamp);
896 ALOGE_IF(
897 error < 0,
898 "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
899 strerror(-error));
900
901 // Don't bother processing this frame if a pause was requested
Steven Thomas282a5ed2017-02-07 18:07:01 -0800902 std::lock_guard<std::mutex> post_thread_lock(post_thread_state_mutex_);
903 if (post_thread_state_ == PostThreadState::kPauseRequested) {
Alex Vakulenkoa8a92782017-01-27 14:41:57 -0800904 continue;
905 }
906 }
907
908 ++vsync_count_;
909
910 static double last_print_time = -1;
911 double current_time = GetSystemClockSec();
912 if (last_print_time < 0 || current_time - last_print_time > 3) {
913 last_print_time = current_time;
914 }
915
916 if (pose_client_) {
917 // Signal the pose service with vsync info.
918 // Display timestamp is in the middle of scanout.
919 privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
920 vsync_timestamp + photon_offset_ns,
921 ns_per_frame, right_eye_photon_offset_ns);
922 }
923
924 bool layer_config_changed = UpdateLayerConfig(&compositor_surfaces);
925
926 if (layer_config_changed) {
927 frame_time_history.ResetWithSeed(
928 GuessFrameTime(compositor_surfaces.size()));
929 frame_time_backlog.clear();
930 } else {
931 UpdateFrameTimeHistory(&frame_time_backlog, kFrameTimeBacklogMax,
932 &fence_info_buffer, &frame_time_history);
933 }
934
935 // Get our current best estimate at how long the next frame will take to
936 // render, based on how long previous frames took to render. Use this
937 // estimate to decide when to wake up for EDS.
938 int64_t frame_time_estimate =
939 frame_time_history.GetSampleCount() == 0
940 ? GuessFrameTime(compositor_surfaces.size())
941 : frame_time_history.GetAverage();
942 frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
943 DebugHudData::data.hwc_latency = frame_time_estimate;
944
945 // Signal all of the vsync clients. Because absolute time is used for the
946 // wakeup time below, this can take a little time if necessary.
947 if (vsync_callback_)
948 vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
949 vsync_count_);
950
951 {
952 // Sleep until async EDS wakeup time.
953 ATRACE_NAME("sleep");
954
955 int64_t display_time_est = vsync_timestamp + ns_per_frame;
956 int64_t now = GetSystemClockNs();
957 int64_t frame_finish_time_est = now + frame_time_estimate;
958 int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
959
960 ATRACE_INT64("sleep_time_ns", sleep_time_ns);
961 if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
962 ATRACE_INT("frame_skip_count", ++frame_skip_count_);
963 ALOGE(
964 "HardwareComposer::PostThread: Missed frame schedule, drop "
965 "frame. Expected frame miss: %.1fms",
966 static_cast<double>(frame_finish_time_est - display_time_est) /
967 1000000);
968
969 // There are several reasons we might skip a frame, but one possibility
970 // is we mispredicted the frame time. Clear out the frame time history.
971 frame_time_history.ResetWithSeed(
972 GuessFrameTime(compositor_surfaces.size()));
973 frame_time_backlog.clear();
974 DebugHudData::data.hwc_frame_stats.SkipFrame();
975
976 continue;
977 } else {
978 // Make the transition more obvious in systrace when the frame skip
979 // happens above.
980 ATRACE_INT("frame_skip_count", 0);
981 }
982
983 if (sleep_time_ns > 0) {
984 error = SleepUntil(display_time_est - frame_time_estimate);
985 ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
986 strerror(-error));
987 }
988 }
989
990 DebugHudData::data.hwc_frame_stats.AddFrame();
991
992 int64_t frame_start_time = GetSystemClockNs();
993
994 // Setup the output buffer for the compositor. This needs to happen before
995 // you draw with the compositor.
996 if (gpu_layer_ != nullptr) {
997 gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
998 }
999
1000 // Call PostLayers now before performing the GL code for the compositor to
1001 // avoid missing the deadline that can cause the lower-level hwc to get
1002 // permanently backed up.
1003 PostLayers(layer_config_changed);
1004
1005 PostCompositorBuffers(compositor_surfaces);
1006
1007 if (gpu_layer_ != nullptr) {
1008 // Note, with scanline racing, this draw is timed along with the post
1009 // layers to finish just in time.
1010 LocalHandle frame_fence_fd;
1011 compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
1012 if (frame_fence_fd) {
1013 LOG_ALWAYS_FATAL_IF(frame_time_backlog.size() >= kFrameTimeBacklogMax,
1014 "Frame time backlog exceeds capacity");
1015 frame_time_backlog.push_back(
1016 {frame_start_time, std::move(frame_fence_fd)});
1017 }
1018 } else if (!layer_config_changed) {
1019 frame_time_history.AddSample(GetSystemClockNs() - frame_start_time);
1020 }
1021
1022 HandlePendingScreenshots();
1023 }
1024
1025 // TODO(skiazyk): Currently the compositor is not fully releasing its EGL
1026 // context, which seems to prevent the thread from exiting properly.
1027 // This shouldn't be too hard to address, I just don't have time right now.
1028 compositor_.Shutdown();
1029}
1030
1031bool HardwareComposer::UpdateLayerConfig(
1032 std::vector<std::shared_ptr<DisplaySurface>>* compositor_surfaces) {
Steven Thomas282a5ed2017-02-07 18:07:01 -08001033 std::lock_guard<std::mutex> layer_lock(layer_mutex_);
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001034
1035 if (!display_surfaces_updated_)
1036 return false;
1037
1038 display_surfaces_updated_ = false;
1039 DebugHudData::data.ResetLayers();
1040
1041 // Update compositor layers.
1042 {
1043 ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1044 compositor_.UpdateSurfaces(display_surfaces_);
1045 compositor_surfaces->clear();
1046 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1047 const auto& surface = display_surfaces_[i];
1048 if (!(surface->flags() &
1049 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
1050 compositor_surfaces->push_back(surface);
1051 }
1052 }
1053 }
1054
1055 if (!hardware_layers_need_update_)
1056 return true;
1057
1058 // Update hardware layers.
1059
1060 ATRACE_NAME("UpdateLayerConfig_HwLayers");
1061 hardware_layers_need_update_ = false;
1062
1063 // Update the display layers in a non-destructive fashion.
1064
1065 // Create a map from surface id to hardware layer
1066 std::map<int, Layer*> display_surface_layers;
1067
1068 for (size_t i = 0; i < active_layer_count_; ++i) {
1069 auto layer = layers_[i];
1070 int surface_id = layer->GetSurfaceId();
1071
1072 auto found =
1073 std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1074 [surface_id](const auto& surface) {
1075 return surface->surface_id() == surface_id;
1076 });
1077
1078 if (found != display_surfaces_.end()) {
1079 display_surface_layers[surface_id] = layer;
1080 }
1081 }
1082
1083 bool has_gpu_layer = std::any_of(
1084 display_surfaces_.begin(), display_surfaces_.end(),
1085 [](const auto& surface) {
1086 return !(surface->flags() &
1087 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1088 });
1089
1090 if (!has_gpu_layer) {
1091 gpu_layer_ = nullptr;
1092 }
1093
1094 auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1095 int surface_id = layer->GetSurfaceId();
1096 if (surface_id >= 0) {
1097 return display_surface_layers.count(surface_id) > 0;
1098 } else {
1099 return has_gpu_layer;
1100 }
1101 };
1102
1103 // Compress the in-use layers to the top of the list
1104 auto part = std::partition(
1105 layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1106
1107 size_t new_active_layer_count = part - layers_.begin();
1108
1109 // Clear any unused layers
1110 for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1111 layers_[i]->Reset();
1112 }
1113
1114 active_layer_count_ = new_active_layer_count;
1115
1116 bool gpu_layer_applied = false;
1117
1118 // Create/update all of the hardware layers
1119 for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1120 const auto& surface = display_surfaces_[i];
1121 bool is_hw_surface =
1122 surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1123 hwc2_blend_mode_t blending =
1124 i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1125
1126 DebugHudData::data.SetLayerInfo(
1127 i, surface->width(), surface->height(),
1128 !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1129
1130 if (!is_hw_surface && gpu_layer_applied) {
1131 continue;
1132 }
1133
1134 Layer* target_layer;
1135 bool existing_layer = false;
1136
1137 if (is_hw_surface) {
1138 auto it = display_surface_layers.find(surface->surface_id());
1139
1140 if (it != display_surface_layers.end()) {
1141 target_layer = it->second;
1142 existing_layer = true;
1143 }
1144 } else if (gpu_layer_ != nullptr) {
1145 target_layer = gpu_layer_;
1146 existing_layer = true;
1147 }
1148
1149 if (!existing_layer) {
1150 if (active_layer_count_ >= kMaxHardwareLayers) {
1151 ALOGI("HardwareComposer: More than %d hardware layers requested.",
1152 kMaxHardwareLayers);
1153 break;
1154 } else {
1155 target_layer = layers_[active_layer_count_];
1156 ++active_layer_count_;
1157 }
1158
1159 ALOGD_IF(TRACE,
1160 "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1161 "layer=%zd",
1162 surface->surface_id(), i);
1163
1164 if (is_hw_surface) {
1165 target_layer->Setup(surface, blending, display_transform_,
1166 HWC2_COMPOSITION_DEVICE, i);
1167 } else {
1168 gpu_layer_ = target_layer;
1169 target_layer->Setup(compositor_.GetBuffer(), blending,
1170 display_transform_, HWC2_COMPOSITION_DEVICE, i);
1171 }
1172 } else {
1173 ALOGD_IF(TRACE,
1174 "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1175 "-> layer=%zd",
1176 surface->surface_id(), i);
1177
1178 target_layer->SetBlending(blending);
1179 target_layer->SetZOrderIndex(i);
1180 target_layer->UpdateLayerSettings();
1181 }
1182
1183 gpu_layer_applied = !is_hw_surface;
1184 }
1185
1186 ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1187 active_layer_count_);
1188
1189 return true;
1190}
1191
1192void HardwareComposer::PostCompositorBuffers(
1193 const std::vector<std::shared_ptr<DisplaySurface>>& compositor_surfaces) {
1194 ATRACE_NAME("PostCompositorBuffers");
1195 for (const auto& surface : compositor_surfaces) {
1196 compositor_.PostBuffer(surface);
1197 }
1198}
1199
1200void HardwareComposer::UpdateFrameTimeHistory(
1201 std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1202 FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1203 while (!backlog->empty()) {
1204 const auto& frame_time_record = backlog->front();
1205 int64_t end_time = 0;
1206 bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1207 fence_info_buffer, &end_time);
1208 if (frame_finished) {
1209 int64_t frame_duration = end_time - frame_time_record.start_time;
1210 history->AddSample(frame_duration);
1211 // Our backlog is tiny (2 elements), so erasing from the front is ok
1212 backlog->erase(backlog->begin());
1213 } else {
1214 break;
1215 }
1216 }
1217
1218 if (backlog->size() == static_cast<size_t>(backlog_max)) {
1219 // Yikes, something must've gone wrong if our oldest frame hasn't finished
1220 // yet. Give up on waiting for it.
1221 const auto& stale_frame_time_record = backlog->front();
1222 int64_t frame_duration =
1223 GetSystemClockNs() - stale_frame_time_record.start_time;
1224 backlog->erase(backlog->begin());
1225 history->AddSample(frame_duration);
1226 ALOGW("Frame didn't finish after %.1fms",
1227 static_cast<double>(frame_duration) / 1000000);
1228 }
1229}
1230
1231bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1232 FenceInfoBuffer* fence_info_buffer,
1233 int64_t* timestamp) {
1234 int result = -1;
1235 int sync_result = sync_wait(frame_fence_fd, 0);
1236 if (sync_result == 0) {
1237 result =
1238 GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1239 if (result < 0) {
1240 ALOGE("Failed getting signaled timestamp from fence");
1241 }
1242 } else if (errno != ETIME) {
1243 ALOGE("sync_wait on frame fence failed");
1244 }
1245 return result >= 0;
1246}
1247
1248void HardwareComposer::HandlePendingScreenshots() {
1249 // Take a screenshot of the requested layer, if available.
1250 // TODO(eieio): Look into using virtual displays to composite the layer stack
1251 // into a single output buffer that can be returned to the screenshot clients.
1252 if (active_layer_count_ > 0) {
1253 if (auto screenshot_service = ScreenshotService::GetInstance()) {
1254 if (screenshot_service->IsScreenshotRequestPending()) {
1255 ATRACE_NAME("screenshot");
1256 screenshot_service->TakeIfNeeded(layers_, compositor_);
1257 }
1258 } else {
1259 ALOGW(
1260 "HardwareComposer::HandlePendingScreenshots: Failed to get "
1261 "screenshot service!");
1262 }
1263 }
1264}
1265
1266void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1267 vsync_callback_ = callback;
1268}
1269
1270void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1271 hwc2_display_t /*display*/) {
1272 // TODO(eieio): implement invalidate callbacks.
1273}
1274
1275void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1276 hwc2_display_t /*display*/,
1277 int64_t /*timestamp*/) {
1278 ATRACE_NAME(__PRETTY_FUNCTION__);
1279 // Intentionally empty. HWC may require a callback to be set to enable vsync
1280 // signals. We bypass this callback thread by monitoring the vsync event
1281 // directly, but signals still need to be enabled.
1282}
1283
1284void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1285 hwc2_display_t /*display*/,
1286 hwc2_connection_t /*connected*/) {
1287 // TODO(eieio): implement display hotplug callbacks.
1288}
1289
Steven Thomas3cfac282017-02-06 12:29:30 -08001290void HardwareComposer::OnHardwareComposerRefresh() {
1291 // TODO(steventhomas): Handle refresh.
1292}
1293
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001294void HardwareComposer::SetBacklightBrightness(int brightness) {
1295 if (backlight_brightness_fd_) {
1296 std::array<char, 32> text;
1297 const int length = snprintf(text.data(), text.size(), "%d", brightness);
1298 write(backlight_brightness_fd_.Get(), text.data(), length);
1299 }
1300}
1301
1302Layer::Layer()
1303 : hwc2_hidl_(nullptr),
1304 surface_index_(-1),
1305 hardware_composer_layer_(0),
1306 display_metrics_(nullptr),
1307 blending_(HWC2_BLEND_MODE_NONE),
1308 transform_(HWC_TRANSFORM_NONE),
1309 composition_type_(HWC2_COMPOSITION_DEVICE),
1310 surface_rect_functions_applied_(false) {}
1311
1312void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1313 hwc2_hidl_ = hwc2_hidl;
1314 display_metrics_ = metrics;
1315}
1316
1317void Layer::Reset() {
1318 const int ret = acquired_buffer_.Release(std::move(release_fence_));
1319 ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1320 strerror(-ret));
1321
1322 if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1323 hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1324 hardware_composer_layer_ = 0;
1325 }
1326
1327 surface_index_ = static_cast<size_t>(-1);
1328 blending_ = HWC2_BLEND_MODE_NONE;
1329 transform_ = HWC_TRANSFORM_NONE;
1330 composition_type_ = HWC2_COMPOSITION_DEVICE;
1331 direct_buffer_ = nullptr;
1332 surface_ = nullptr;
1333 acquire_fence_fd_.Close();
1334 surface_rect_functions_applied_ = false;
1335}
1336
1337void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1338 hwc2_blend_mode_t blending, hwc_transform_t transform,
1339 hwc2_composition_t composition_type, size_t index) {
1340 Reset();
1341 surface_index_ = index;
1342 surface_ = surface;
1343 blending_ = blending;
1344 transform_ = transform;
1345 composition_type_ = composition_type;
1346 CommonLayerSetup();
1347}
1348
1349void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1350 hwc2_blend_mode_t blending, hwc_transform_t transform,
1351 hwc2_composition_t composition_type, size_t z_order) {
1352 Reset();
1353 surface_index_ = z_order;
1354 direct_buffer_ = buffer;
1355 blending_ = blending;
1356 transform_ = transform;
1357 composition_type_ = composition_type;
1358 CommonLayerSetup();
1359}
1360
1361void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1362 direct_buffer_ = buffer;
1363}
1364
1365void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1366
1367void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1368
1369IonBuffer* Layer::GetBuffer() {
1370 if (direct_buffer_)
1371 return direct_buffer_.get();
1372 else if (acquired_buffer_.IsAvailable())
1373 return acquired_buffer_.buffer()->buffer();
1374 else
1375 return nullptr;
1376}
1377
1378void Layer::UpdateLayerSettings() {
1379 if (!IsLayerSetup()) {
1380 ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1381 return;
1382 }
1383
1384 int32_t ret = HWC2_ERROR_NONE;
1385
1386 hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1387
1388 ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1389 display, hardware_composer_layer_,
1390 (Hwc2::IComposerClient::Composition)composition_type_);
1391 ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1392 ret);
1393 // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1394 // hardware_composer_layer_,
1395 // (Hwc2::IComposerClient::Transform)
1396 // transform_);
1397 // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1398
1399 // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1400 // hardware_composer_device_, display, hardware_composer_layer_,
1401 // blending_);
1402 ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1403 display, hardware_composer_layer_,
1404 (Hwc2::IComposerClient::BlendMode)blending_);
1405 ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1406
1407 Hwc2::IComposerClient::Rect display_frame;
1408 display_frame.left = 0;
1409 display_frame.top = 0;
1410 display_frame.right = display_metrics_->width;
1411 display_frame.bottom = display_metrics_->height;
1412 ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1413 display, hardware_composer_layer_, display_frame);
1414 ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1415 ret);
1416
1417 std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1418 visible_region[0] = display_frame;
1419 ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1420 display, hardware_composer_layer_, visible_region);
1421 ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1422 ret);
1423
1424 ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1425 hardware_composer_layer_, 1.0f);
1426 ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1427
1428 ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1429 surface_index_);
1430 ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1431}
1432
1433void Layer::CommonLayerSetup() {
1434 int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1435 &hardware_composer_layer_);
1436
1437 ALOGE_IF(ret,
1438 "HardwareComposer: Failed to create layer on primary display : %d",
1439 ret);
1440
1441 UpdateLayerSettings();
1442}
1443
1444void Layer::Prepare() {
1445 int right, bottom;
1446 buffer_handle_t handle;
1447
1448 if (surface_) {
1449 // Only update the acquired buffer when one is either available or this is
1450 // the first time through.
1451 if (surface_->IsBufferAvailable()) {
1452 // If we previously set this to a solid color layer to stall for time,
1453 // revert it to a device layer.
1454 if (acquired_buffer_.IsEmpty() &&
1455 composition_type_ != HWC2_COMPOSITION_DEVICE) {
1456 composition_type_ = HWC2_COMPOSITION_DEVICE;
1457 hwc2_hidl_->setLayerCompositionType(
1458 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1459 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1460 }
1461
1462 DebugHudData::data.AddLayerFrame(surface_index_);
1463 acquired_buffer_.Release(std::move(release_fence_));
1464 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1465
1466 // Basic latency stopgap for when the application misses a frame:
1467 // If the application recovers on the 2nd or 3rd (etc) frame after
1468 // missing, this code will skip a frame to catch up by checking if
1469 // the next frame is also available.
1470 if (surface_->IsBufferAvailable()) {
1471 DebugHudData::data.SkipLayerFrame(surface_index_);
1472 ATRACE_NAME("DropToCatchUp");
1473 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1474 acquired_buffer_ = surface_->AcquireCurrentBuffer();
1475 }
1476 ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1477 } else if (acquired_buffer_.IsEmpty()) {
1478 // While we are waiting for a buffer, set this to be an empty layer
1479 if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1480 composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1481 hwc2_hidl_->setLayerCompositionType(
1482 HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1483 (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1484
1485 Hwc2::IComposerClient::Color layer_color = {
1486 0, 0, 0, 0,
1487 };
1488 hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1489 layer_color);
1490 }
1491 return;
1492 }
1493 right = acquired_buffer_.buffer()->width();
1494 bottom = acquired_buffer_.buffer()->height();
1495 handle = acquired_buffer_.buffer()->native_handle();
1496 acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1497 } else {
1498 right = direct_buffer_->width();
1499 bottom = direct_buffer_->height();
1500 handle = direct_buffer_->handle();
1501 acquire_fence_fd_.Close();
1502 }
1503
1504 int32_t ret = HWC2_ERROR_NONE;
1505
1506 if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1507 ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
Chia-I Wu06d63de2017-01-04 14:58:51 +08001508 hardware_composer_layer_, 0,
1509 handle,
Alex Vakulenkoa8a92782017-01-27 14:41:57 -08001510 acquire_fence_fd_.Get());
1511
1512 ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1513 }
1514
1515 if (!surface_rect_functions_applied_) {
1516 Hwc2::IComposerClient::FRect crop_rect = {
1517 0, 0, static_cast<float>(right), static_cast<float>(bottom),
1518 };
1519 hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1520 hardware_composer_layer_, crop_rect);
1521
1522 ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1523 ret);
1524
1525// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1526// it must/cannot be called?
1527#ifdef QCOM_BSP
1528 hwc_rect_t damage_rect = {
1529 0, 0, right, bottom,
1530 };
1531 hwc_region_t damage = {
1532 1, &damage_rect,
1533 };
1534 // ret = hwc2_funcs_->set_layer_surface_damage(
1535 // hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1536 // hardware_composer_layer_, damage);
1537 // uses a std::vector as the listing
1538 // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1539 // hardware_composer_layer_, vector here);
1540
1541 ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1542 ret);
1543#endif
1544
1545 surface_rect_functions_applied_ = true;
1546 }
1547}
1548
1549void Layer::Finish(int release_fence_fd) {
1550 release_fence_.Reset(release_fence_fd);
1551}
1552
1553void Layer::Drop() { acquire_fence_fd_.Close(); }
1554
1555} // namespace dvr
1556} // namespace android