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