hardware_composer.cpp revision 050b2c83304bd16ec3a838da08b6ba6acf6a3af4
1a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "hardware_composer.h"
2a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
3a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <log/log.h>
4a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <cutils/properties.h>
5a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <cutils/sched_policy.h>
6a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <fcntl.h>
7a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <poll.h>
8a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sync/sync.h>
9a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/eventfd.h>
10a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/prctl.h>
11a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/resource.h>
12a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/system_properties.h>
13a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <sys/timerfd.h>
14a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <unistd.h>
15a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <utils/Trace.h>
16a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
17a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <algorithm>
18a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <functional>
19a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <map>
20a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
21a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <dvr/performance_client_api.h>
22a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/clock_ns.h>
23a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/display_types.h>
24a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/pose_client_internal.h>
25a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/sync_util.h>
26a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
27a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "debug_hud_data.h"
28a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "screenshot_service.h"
29a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
30a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::LocalHandle;
31a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
32a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace android {
33a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace dvr {
34a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
35a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace {
36a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
37a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// If the number of pending fences goes over this count at the point when we
38a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// are about to submit a new frame to HWC, we will drop the frame. This should
39a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// be a signal that the display driver has begun queuing frames. Note that with
40a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// smart displays (with RAM), the fence is signaled earlier than the next vsync,
41a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// at the point when the DMA to the display completes. Currently we use a smart
42a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// display and the EDS timing coincides with zero pending fences, so this is 0.
43a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr int kAllowedPendingFenceCount = 0;
44a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
45a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// If we think we're going to miss vsync by more than this amount, skip the
46a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// frame.
47a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr int64_t kFrameSkipThresholdNs = 4000000;  // 4ms
48a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
49a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Counter PostLayers() deficiency by requiring apps to produce a frame at least
50a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// 2.5ms before vsync. See b/28881672.
51a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr int64_t kFrameTimeEstimateMin = 2500000;  // 2.5ms
52a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
53a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr size_t kDefaultDisplayConfigCount = 32;
54a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
55a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr float kMetersPerInch = 0.0254f;
56a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
57a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kBacklightBrightnessSysFile[] =
58a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    "/sys/class/leds/lcd-backlight/brightness";
59a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
60a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kPrimaryDisplayVSyncEventFile[] =
61a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    "/sys/class/graphics/fb0/vsync_event";
62a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
63a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";
64a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
65a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kDvrPerformanceProperty[] = "sys.dvr.performance";
66a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
67a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kRightEyeOffsetProperty[] = "dreamos.right_eye_offset_ns";
68a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
69a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Returns our best guess for the time the compositor will spend rendering the
70a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// next frame.
71a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint64_t GuessFrameTime(int compositor_visible_layer_count) {
72a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // The cost of asynchronous EDS and lens warp is currently measured at 2.5ms
73a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // for one layer and 7ms for two layers, but guess a higher frame time to
74a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // account for CPU overhead. This guess is only used before we've measured the
75a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // actual time to render a frame for the current compositor configuration.
76a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  switch (compositor_visible_layer_count) {
77a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    case 0:
78a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 500000;  // .5ms
79a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    case 1:
80a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 5000000;  // 5ms
81a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    default:
82a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 10500000;  // 10.5ms
83a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
84a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
85a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
86a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Get time offset from a vsync to when the pose for that vsync should be
87a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// predicted out to. For example, if scanout gets halfway through the frame
88a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// at the halfway point between vsyncs, then this could be half the period.
89a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// With global shutter displays, this should be changed to the offset to when
90a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// illumination begins. Low persistence adds a frame of latency, so we predict
91a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// to the center of the next frame.
92a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoinline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
93a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return (vsync_period_ns * 150) / 100;
94a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
95a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
96a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}  // anonymous namespace
97a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
98a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoHardwareComposer::HardwareComposer()
99a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  : HardwareComposer(nullptr) {
100a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
101a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
102a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoHardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
103016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk    : initialized_(false),
104016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk      hwc2_hidl_(hwc2_hidl),
105a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display_transform_(HWC_TRANSFORM_NONE),
106050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      active_surfaces_updated_(false),
107a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      active_layer_count_(0),
108a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      gpu_layer_(nullptr),
109050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      post_thread_enabled_(false),
110050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      post_thread_running_(false),
111050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      post_thread_quit_requested_(false),
112050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      post_thread_interrupt_event_fd_(-1),
113a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      backlight_brightness_fd_(-1),
114a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      primary_display_vsync_event_fd_(-1),
115a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      primary_display_wait_pp_fd_(-1),
116a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      vsync_sleep_timer_fd_(-1),
117a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      last_vsync_timestamp_(0),
118a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      vsync_count_(0),
119a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      frame_skip_count_(0),
120a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      pose_client_(nullptr) {
121a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(),
122a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                 [](auto& layer) { return &layer; });
123a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
124a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  callbacks_ = new ComposerCallback;
125a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
126a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
127a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoHardwareComposer::~HardwareComposer(void) {
128050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  std::unique_lock<std::mutex> lock(post_thread_mutex_);
129050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (post_thread_.joinable()) {
130050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    post_thread_quit_requested_ = true;
131050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    post_thread_cond_var_.notify_all();
132050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    post_thread_.join();
133050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
134a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
135a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
136016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazykbool HardwareComposer::Initialize() {
137016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  if (initialized_) {
138016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk    ALOGE("HardwareComposer::Initialize: already initialized.");
139a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return false;
140a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
141a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
142a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = HWC2_ERROR_NONE;
143a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
144016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  Hwc2::Config config;
145016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
146a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
147a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
148016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk    ALOGE("HardwareComposer: Failed to get current display config : %d",
149016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk          config);
150a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return false;
151a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
152a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
153016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  ret =
154016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
155a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
156a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
157016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk    ALOGE(
158016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk        "HardwareComposer: Failed to get display attributes for current "
159016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk        "configuration : %d",
160016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk        ret);
161a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return false;
162a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
163a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
164a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGI(
165a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      "HardwareComposer: primary display attributes: width=%d height=%d "
166a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      "vsync_period_ns=%d DPI=%dx%d",
167a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      native_display_metrics_.width, native_display_metrics_.height,
168a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
169a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      native_display_metrics_.dpi.y);
170a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
171016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  // Set the display metrics but never use rotation to avoid the long latency of
172016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  // rotation processing in hwc.
173016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  display_transform_ = HWC_TRANSFORM_NONE;
174016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  display_metrics_ = native_display_metrics_;
175016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk
176050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  post_thread_interrupt_event_fd_.Reset(
177050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
178050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  LOG_ALWAYS_FATAL_IF(
179050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      !post_thread_interrupt_event_fd_,
180050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      "HardwareComposer: Failed to create interrupt event fd : %s",
181050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      strerror(errno));
182050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
183050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  post_thread_ = std::thread(&HardwareComposer::PostThread, this);
184050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
185016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  initialized_ = true;
186016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk
187016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk  return initialized_;
188016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk}
189016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk
190050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::Enable() {
191050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  std::lock_guard<std::mutex> lock(post_thread_mutex_);
192050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  post_thread_enabled_ = true;
193050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  post_thread_cond_var_.notify_all();
194050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas}
1957480c060cb3466d97ec3125d61bbace153f534c8Jin Qian
196050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::Disable() {
197050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  std::unique_lock<std::mutex> lock(post_thread_mutex_);
198050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  post_thread_enabled_ = false;
199050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (post_thread_running_) {
200050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    // Write to the interrupt fd to get fast interrupt of the post thread
201050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    int error = eventfd_write(post_thread_interrupt_event_fd_.Get(), 1);
202050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    ALOGW_IF(error,
203050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "HardwareComposer::Disable: could not write post "
204050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "thread interrupt event fd : %s",
205050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             strerror(errno));
206050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
207050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    post_thread_cond_var_.wait(lock, [this] { return !post_thread_running_; });
208050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
209050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    // Read the interrupt fd to clear its state
210050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    uint64_t interrupt_count= 0;
211050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    error = eventfd_read(post_thread_interrupt_event_fd_.Get(),
212050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                         &interrupt_count);
213050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    ALOGW_IF(error,
214050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "HardwareComposer::Disable: could not read post "
215050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "thread interrupt event fd : %s",
216050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             strerror(errno));
217050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
218050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas}
2197480c060cb3466d97ec3125d61bbace153f534c8Jin Qian
220050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool HardwareComposer::PostThreadHasWork() {
221050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  return !display_surfaces_.empty() ||
222050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      (active_surfaces_updated_ && !active_surfaces_.empty());
223050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas}
224a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
225050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::OnPostThreadResumed() {
226a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  constexpr int format = HAL_PIXEL_FORMAT_RGBA_8888;
227a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  constexpr int usage =
228a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER;
229a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
230a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  framebuffer_target_ = std::make_shared<IonBuffer>(
231a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      native_display_metrics_.width, native_display_metrics_.height, format,
232a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      usage);
233a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
234a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Associate each Layer instance with a hardware composer layer.
235a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (auto layer : layers_) {
236a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
237a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
238a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
239a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Connect to pose service.
240a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  pose_client_ = dvrPoseCreate();
241a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
242a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
243050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  EnableVsync(true);
244a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
245050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // TODO(skiazyk): We need to do something about accessing this directly,
246050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // supposedly there is a backlight service on the way.
247050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // TODO(steventhomas): When we change the backlight setting, will surface
248050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // flinger (or something else) set it back to its original value once we give
249050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // control of the display back to surface flinger?
250050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  SetBacklightBrightness(255);
251282a5ed48f64e4010f97ca4077e3bd4b54ba3268Steven Thomas
252050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Initialize the GPU compositor.
253050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
254050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                      "Failed to initialize the compositor");
255a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
256050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Trigger target-specific performance mode change.
257050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  property_set(kDvrPerformanceProperty, "performance");
258a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
259a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
260050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::OnPostThreadPaused() {
261a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  retire_fence_fds_.clear();
262a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  gpu_layer_ = nullptr;
263a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
264050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // We have to destroy the layers to fully clear hwc device state before
265050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // handing off back to surface flinger
266a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
267a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    layers_[i]->Reset();
268a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
269a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
270a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  active_layer_count_ = 0;
271a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
272a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  framebuffer_target_.reset();
273a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
274050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  display_surfaces_.clear();
275050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  compositor_surfaces_.clear();
276050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
277050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Since we're clearing display_surfaces_ we'll need an update.
278050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  active_surfaces_updated_ = true;
279a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
280050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (pose_client_) {
281a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    dvrPoseDestroy(pose_client_);
282050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    pose_client_ = nullptr;
283050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
284f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas
285050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  EnableVsync(false);
286050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
287050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  frame_time_history_.ResetWithSeed(GuessFrameTime(0));
288050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  frame_time_backlog_.clear();
289050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
290050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  compositor_.Shutdown();
291050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
292050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Trigger target-specific performance mode change.
293050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  property_set(kDvrPerformanceProperty, "idle");
294a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
295a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
296a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoDisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
297a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  vec2i screen_size(display_metrics_.width, display_metrics_.height);
298a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  DisplayOrientation orientation =
299a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      (display_metrics_.width > display_metrics_.height
300a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           ? DisplayOrientation::kLandscape
301a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           : DisplayOrientation::kPortrait);
302a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
303a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
304a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  float meters_per_pixel_x = kMetersPerInch / dpi_x;
305a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  float meters_per_pixel_y = kMetersPerInch / dpi_y;
306a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
307a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  double frame_duration_s =
308a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
309a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // TODO(hendrikw): Hard coding to 3mm.  The Pixel is actually 4mm, but it
310a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //                 seems that their tray to lens distance is wrong too, which
311a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //                 offsets this, at least for the pixel.
312a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  float border_size = 0.003f;
313a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return DisplayMetrics(screen_size, meters_per_pixel, border_size,
314a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                        static_cast<float>(frame_duration_s), orientation);
315a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
316a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
317a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::Validate(hwc2_display_t display) {
318a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  uint32_t num_types;
319a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  uint32_t num_requests;
320a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t error =
321a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
322a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
323a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (error == HWC2_ERROR_HAS_CHANGES) {
324a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // TODO(skiazyk): We might need to inspect the requested changes first, but
325a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // so far it seems like we shouldn't ever hit a bad state.
326a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
327a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    //                                               display);
328a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
329a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
330a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
331a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return error;
332a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
333a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
334a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::EnableVsync(bool enabled) {
335a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return (int32_t)hwc2_hidl_->setVsyncEnabled(
336a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      HWC_DISPLAY_PRIMARY,
337a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
338a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                             : HWC2_VSYNC_DISABLE));
339a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
340a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
341a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::Present(hwc2_display_t display) {
342a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t present_fence;
343a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
344a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
345a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // According to the documentation, this fence is signaled at the time of
346a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // vsync/DMA for physical displays.
347a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (error == HWC2_ERROR_NONE) {
348a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
349a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    retire_fence_fds_.emplace_back(present_fence);
350a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  } else {
351a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_INT("HardwareComposer: PresentResult", error);
352a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
353a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
354a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return error;
355a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
356a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
357a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
358a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                              hwc2_config_t config,
359a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                              hwc2_attribute_t attribute,
360a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                              int32_t* out_value) const {
361a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return (int32_t)hwc2_hidl_->getDisplayAttribute(
362a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
363a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
364a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
365a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::GetDisplayMetrics(
366a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc2_display_t display, hwc2_config_t config,
367a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    HWCDisplayMetrics* out_metrics) const {
368a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = HWC2_ERROR_NONE;
369a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
370a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
371a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            &out_metrics->width);
372a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
373a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Failed to get display width");
374a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return ret;
375a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
376a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
377a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
378a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            &out_metrics->height);
379a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
380a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Failed to get display height");
381a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return ret;
382a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
383a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
384a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
385a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            &out_metrics->vsync_period_ns);
386a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
387a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Failed to get display height");
388a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return ret;
389a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
390a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
391a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
392a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            &out_metrics->dpi.x);
393a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
394a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Failed to get display DPI X");
395a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return ret;
396a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
397a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
398a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
399a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            &out_metrics->dpi.y);
400a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret != HWC2_ERROR_NONE) {
401a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Failed to get display DPI Y");
402a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return ret;
403a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
404a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
405a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return HWC2_ERROR_NONE;
406a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
407a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
408a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
409a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::string debug_str = hwc2_hidl_->dumpDebugInfo();
410a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGI("%s", debug_str.c_str());
411a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
412a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (buffer == nullptr) {
413a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    *out_size = debug_str.size();
414a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  } else {
415a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
416a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
417a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
418a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
419a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
420a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
421a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// there.
422a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
423a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ATRACE_NAME("HardwareComposer::PostLayers");
424a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
425a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Setup the hardware composer layers with current buffers.
426a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < active_layer_count_; i++) {
427a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    layers_[i]->Prepare();
428a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
429a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
430a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Now that we have taken in a frame from the application, we have a chance
431a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // to drop the frame before passing the frame along to HWC.
432a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // If the display driver has become backed up, we detect it here and then
433a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // react by skipping this frame to catch up latency.
434a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  while (!retire_fence_fds_.empty() &&
435a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko         (!retire_fence_fds_.front() ||
436a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
437a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // There are only 2 fences in here, no performance problem to shift the
438a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // array of ints.
439a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    retire_fence_fds_.erase(retire_fence_fds_.begin());
440a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
441a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
442a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const bool is_frame_pending = IsFramePendingInDriver();
443a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const bool is_fence_pending =
444a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      retire_fence_fds_.size() > kAllowedPendingFenceCount;
445a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
446a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (is_fence_pending || is_frame_pending) {
447a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_INT("frame_skip_count", ++frame_skip_count_);
448a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
449a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
450a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGW_IF(is_fence_pending,
451a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko             "Warning: dropping a frame to catch up with HWC (pending = %zd)",
452a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko             retire_fence_fds_.size());
453a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
454a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    for (size_t i = 0; i < active_layer_count_; i++) {
455a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      layers_[i]->Drop();
456a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
457a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return;
458a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  } else {
459a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Make the transition more obvious in systrace when the frame skip happens
460a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // above.
461a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_INT("frame_skip_count", 0);
462a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
463a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
464a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#if TRACE
465a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < active_layer_count_; i++)
466a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
467a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          layers_[i]->GetCompositionType());
468a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#endif
469a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
470a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = HWC2_ERROR_NONE;
471a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
472a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::vector<Hwc2::IComposerClient::Rect> full_region(1);
473a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  full_region[0].left = 0;
474a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  full_region[0].top = 0;
475a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  full_region[0].right = framebuffer_target_->width();
476a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  full_region[0].bottom = framebuffer_target_->height();
477a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
478a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "Error setting client target : %d", ret);
479a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
480a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = Validate(HWC_DISPLAY_PRIMARY);
481a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret) {
482a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
483a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return;
484a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
485a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
486a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = Present(HWC_DISPLAY_PRIMARY);
487a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret) {
488a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer::Present failed; ret=%d", ret);
489a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return;
490a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
491a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
492a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::vector<Hwc2::Layer> out_layers;
493a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::vector<int> out_fences;
494a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
495a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                              &out_fences);
496a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  uint32_t num_elements = out_layers.size();
497a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
498a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
499a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
500a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Perform post-frame bookkeeping. Unused layers are a no-op.
501a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < num_elements; ++i) {
502a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    for (size_t j = 0; j < active_layer_count_; ++j) {
503a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (layers_[j]->GetLayerHandle() == out_layers[i]) {
504a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        layers_[j]->Finish(out_fences[i]);
505a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
506a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
507a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
508a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
509a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
510050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::SetDisplaySurfaces(
511a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
512a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
513a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        surfaces.size());
514050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  std::unique_lock<std::mutex> lock(post_thread_mutex_);
515050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  active_surfaces_ = std::move(surfaces);
516050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  active_surfaces_updated_ = true;
517050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (post_thread_enabled_)
518050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    post_thread_cond_var_.notify_all();
519050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas}
520a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
521050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasint HardwareComposer::PostThreadPollInterruptible(int event_fd) {
522050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  pollfd pfd[2] = {
523050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      {
524050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          .fd = event_fd, .events = POLLPRI | POLLIN, .revents = 0,
525050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      },
526050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      {
527050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          .fd = post_thread_interrupt_event_fd_.Get(),
528050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          .events = POLLPRI | POLLIN,
529050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          .revents = 0,
530050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      },
531050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  };
532050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  int ret, error;
533050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  do {
534050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    ret = poll(pfd, 2, -1);
535050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    error = errno;
536050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    ALOGW_IF(ret < 0,
537050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "HardwareComposer::PostThreadPollInterruptible: Error during "
538050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             "poll(): %s (%d)",
539050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             strerror(error), error);
540050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  } while (ret < 0 && error == EINTR);
5417480c060cb3466d97ec3125d61bbace153f534c8Jin Qian
542050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (ret < 0) {
543050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    return -error;
544050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  } else if (pfd[0].revents != 0) {
545050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    return 0;
546050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  } else if (pfd[1].revents != 0) {
547050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    ALOGI("VrHwcPost thread interrupted");
548050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    return kPostThreadInterrupted;
549050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  } else {
550050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    return 0;
5517480c060cb3466d97ec3125d61bbace153f534c8Jin Qian  }
552a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
553a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
554a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
555a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// (the value of the state) on success or a negative error otherwise.
556a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a
557a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually.
558a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::ReadWaitPPState() {
559a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Gracefully handle when the kernel does not support this feature.
560a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (!primary_display_wait_pp_fd_)
561a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return 0;
562a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
563a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
564a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int ret, error;
565a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
566a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = lseek(wait_pp_fd, 0, SEEK_SET);
567a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
568a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = errno;
569a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
570a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          strerror(error));
571a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
572a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
573a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
574a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  char data = -1;
575a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = read(wait_pp_fd, &data, sizeof(data));
576a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
577a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = errno;
578a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
579a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          strerror(error));
580a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
581a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
582a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
583a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  switch (data) {
584a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    case '0':
585a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 0;
586a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    case '1':
587a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 1;
588a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    default:
589a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGE(
590a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
591a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          data);
592a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return -EINVAL;
593a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
594a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
595a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
596a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Reads the timestamp of the last vsync from the display driver.
597a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a
598a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually.
599a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
600a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int event_fd = primary_display_vsync_event_fd_.Get();
601a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int ret, error;
602a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
603a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // The driver returns data in the form "VSYNC=<timestamp ns>".
604a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::array<char, 32> data;
605a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  data.fill('\0');
606a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
607a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Seek back to the beginning of the event file.
608a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = lseek(event_fd, 0, SEEK_SET);
609a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
610a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = errno;
611a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE(
612a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
613a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "%s",
614a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        strerror(error));
615a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
616a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
617a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
618a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Read the vsync event timestamp.
619a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = read(event_fd, data.data(), data.size());
620a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
621a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = errno;
622a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE_IF(
623a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        error != EAGAIN,
624a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
625a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "%s",
626a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        strerror(error));
627a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
628a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
629a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
630a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = sscanf(data.data(), "VSYNC=%" PRIu64,
631a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               reinterpret_cast<uint64_t*>(timestamp));
632a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
633a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = errno;
634a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE(
635a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
636a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        "%s",
637a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        strerror(error));
638a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
639a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
640a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
641a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return 0;
642a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
643a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
644a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Blocks until the next vsync event is signaled by the display driver.
645a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a
646a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually.
647050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasint HardwareComposer::BlockUntilVSync() {
648050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get());
649a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
650a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
651a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Waits for the next vsync and returns the timestamp of the vsync event. If
652a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// vsync already passed since the last call, returns the latest vsync timestamp
653a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// instead of blocking. This method updates the last_vsync_timeout_ in the
654a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// process.
655a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko//
656a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a
657a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually.
658a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::WaitForVSync(int64_t* timestamp) {
659a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int error;
660a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
661a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Get the current timestamp and decide what to do.
662a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  while (true) {
663a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t current_vsync_timestamp;
664a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    error = ReadVSyncTimestamp(&current_vsync_timestamp);
665a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (error < 0 && error != -EAGAIN)
666a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return error;
667a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
668a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (error == -EAGAIN) {
669a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Vsync was turned off, wait for the next vsync event.
670050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      error = BlockUntilVSync();
671050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      if (error < 0 || error == kPostThreadInterrupted)
672a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        return error;
673a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
674a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Try again to get the timestamp for this new vsync interval.
675a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      continue;
676a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
677a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
678a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Check that we advanced to a later vsync interval.
679a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
680a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
681a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return 0;
682a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
683a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
684a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // See how close we are to the next expected vsync. If we're within 1ms,
685a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // sleep for 1ms and try again.
686a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
687a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const int64_t threshold_ns = 1000000;
688a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
689a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
690a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
691a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
692a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (distance_to_vsync_est > threshold_ns) {
693a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Wait for vsync event notification.
694050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      error = BlockUntilVSync();
695050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      if (error < 0 || error == kPostThreadInterrupted)
696a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        return error;
697a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
698050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      // Sleep for a short time (1 millisecond) before retrying.
699050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      error = SleepUntil(GetSystemClockNs() + 1000000);
700050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      if (error < 0 || error == kPostThreadInterrupted)
701050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        return error;
702a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
703a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
704a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
705a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
706a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
707a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int timer_fd = vsync_sleep_timer_fd_.Get();
708a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const itimerspec wakeup_itimerspec = {
709a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      .it_interval = {.tv_sec = 0, .tv_nsec = 0},
710a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      .it_value = NsToTimespec(wakeup_timestamp),
711a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  };
712a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int ret =
713a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
714a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int error = errno;
715a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (ret < 0) {
716a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
717a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          strerror(error));
718a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return -error;
719a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
720a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
721050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  return PostThreadPollInterruptible(timer_fd);
722a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
723a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
724a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::PostThread() {
725a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // NOLINTNEXTLINE(runtime/int)
726050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
727a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
728a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Set the scheduler to SCHED_FIFO with high priority.
729a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int error = dvrSetSchedulerClass(0, "graphics:high");
730a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  LOG_ALWAYS_FATAL_IF(
731a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      error < 0,
732a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      "HardwareComposer::PostThread: Failed to set scheduler class: %s",
733a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      strerror(-error));
734a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  error = dvrSetCpuPartition(0, "/system/performance");
735a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  LOG_ALWAYS_FATAL_IF(
736a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      error < 0,
737a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      "HardwareComposer::PostThread: Failed to set cpu partition: %s",
738a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      strerror(-error));
739a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
740050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas#if ENABLE_BACKLIGHT_BRIGHTNESS
741050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // TODO(hendrikw): This isn't required at the moment. It's possible that there
742050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  //                 is another method to access this when needed.
743050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Open the backlight brightness control sysfs node.
744050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
745050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  ALOGW_IF(!backlight_brightness_fd_,
746050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas           "HardwareComposer: Failed to open backlight brightness control: %s",
747050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas           strerror(errno));
748050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas#endif // ENABLE_BACKLIGHT_BRIGHTNESS
749f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas
750050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Open the vsync event node for the primary display.
751050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // TODO(eieio): Move this into a platform-specific class.
752050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  primary_display_vsync_event_fd_ =
753050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
754050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  ALOGE_IF(!primary_display_vsync_event_fd_,
755050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas           "HardwareComposer: Failed to open vsync event node for primary "
756050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas           "display: %s",
757050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas           strerror(errno));
758050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
759050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Open the wait pingpong status node for the primary display.
760050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // TODO(eieio): Move this into a platform-specific class.
761050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  primary_display_wait_pp_fd_ =
762050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
763050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  ALOGW_IF(
764050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      !primary_display_wait_pp_fd_,
765050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      "HardwareComposer: Failed to open wait_pp node for primary display: %s",
766050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      strerror(errno));
767050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
768050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Create a timerfd based on CLOCK_MONOTINIC.
769050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
770050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  LOG_ALWAYS_FATAL_IF(
771050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      !vsync_sleep_timer_fd_,
772050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      "HardwareComposer: Failed to create vsync sleep timerfd: %s",
773050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      strerror(errno));
774a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
775a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
776a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
777a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
778a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // TODO(jbates) Query vblank time from device, when such an API is available.
779a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // This value (6.3%) was measured on A00 in low persistence mode.
780a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int64_t vblank_ns = ns_per_frame * 63 / 1000;
781a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
782a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
783a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Check property for overriding right eye offset value.
784a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  right_eye_photon_offset_ns =
785a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
786a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
787050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  compositor_surfaces_.reserve(2);
788a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
789a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  constexpr int kFrameTimeBacklogMax = 2;
790050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  frame_time_backlog_.reserve(kFrameTimeBacklogMax);
791a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
792a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Storage for retrieving fence info.
793a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  FenceInfoBuffer fence_info_buffer;
794a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
795050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  bool was_running = false;
796050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
797a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  while (1) {
798a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_NAME("HardwareComposer::PostThread");
799a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
800282a5ed48f64e4010f97ca4077e3bd4b54ba3268Steven Thomas    {
801050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      std::unique_lock<std::mutex> lock(post_thread_mutex_);
802050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      while (!post_thread_enabled_ || post_thread_quit_requested_ ||
803050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas             !PostThreadHasWork()) {
804050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (was_running) {
805050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          const char* pause_reason = "unknown";
806050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          if (!post_thread_enabled_)
807050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            pause_reason = "disabled";
808050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          else if (post_thread_quit_requested_)
809050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            pause_reason = "quit requested";
810050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          else if (!PostThreadHasWork())
811050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            pause_reason = "no work";
812050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
813050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          OnPostThreadPaused();
814050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          was_running = false;
815050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        }
816050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        post_thread_running_ = false;
817050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        post_thread_cond_var_.notify_all();
818050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (post_thread_quit_requested_)
819050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          return;
820050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        post_thread_cond_var_.wait(lock);
821282a5ed48f64e4010f97ca4077e3bd4b54ba3268Steven Thomas      }
822050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      post_thread_running_ = true;
823050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    }
824050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
825050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!was_running) {
826050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      ALOGI("VrHwcPost thread resumed");
827050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      OnPostThreadResumed();
828050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      was_running = true;
829a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
830a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
831a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t vsync_timestamp = 0;
832a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    {
833a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      std::array<char, 128> buf;
834a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
835a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               vsync_count_ + 1);
836a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ATRACE_NAME(buf.data());
837a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
838a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      error = WaitForVSync(&vsync_timestamp);
839a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGE_IF(
840a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          error < 0,
841a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
842a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          strerror(-error));
843a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Don't bother processing this frame if a pause was requested
844050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      if (error == kPostThreadInterrupted)
845a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        continue;
846a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
847a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
848a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ++vsync_count_;
849a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
850a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (pose_client_) {
851a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Signal the pose service with vsync info.
852a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Display timestamp is in the middle of scanout.
853a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
854a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                vsync_timestamp + photon_offset_ns,
855a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                ns_per_frame, right_eye_photon_offset_ns);
856a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
857a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
858050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    bool layer_config_changed = UpdateLayerConfig();
859a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
860050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!was_running || layer_config_changed) {
861050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      frame_time_history_.ResetWithSeed(
862050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          GuessFrameTime(compositor_surfaces_.size()));
863050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      frame_time_backlog_.clear();
864a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
865050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
866050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                             &fence_info_buffer, &frame_time_history_);
867a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
868a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
869a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Get our current best estimate at how long the next frame will take to
870a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // render, based on how long previous frames took to render. Use this
871a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // estimate to decide when to wake up for EDS.
872a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t frame_time_estimate =
873050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        frame_time_history_.GetSampleCount() == 0
874050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            ? GuessFrameTime(compositor_surfaces_.size())
875050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            : frame_time_history_.GetAverage();
876a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
877a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    DebugHudData::data.hwc_latency = frame_time_estimate;
878a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
879a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Signal all of the vsync clients. Because absolute time is used for the
880a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // wakeup time below, this can take a little time if necessary.
881a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (vsync_callback_)
882a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
883a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                      vsync_count_);
884a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
885a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    {
886a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Sleep until async EDS wakeup time.
887a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ATRACE_NAME("sleep");
888a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
889a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      int64_t display_time_est = vsync_timestamp + ns_per_frame;
890a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      int64_t now = GetSystemClockNs();
891a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      int64_t frame_finish_time_est = now + frame_time_estimate;
892a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
893a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
894a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ATRACE_INT64("sleep_time_ns", sleep_time_ns);
895a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
896a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ATRACE_INT("frame_skip_count", ++frame_skip_count_);
897a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ALOGE(
898a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            "HardwareComposer::PostThread: Missed frame schedule, drop "
899a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            "frame. Expected frame miss: %.1fms",
900a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            static_cast<double>(frame_finish_time_est - display_time_est) /
901a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                1000000);
902a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
903a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        // There are several reasons we might skip a frame, but one possibility
904a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        // is we mispredicted the frame time. Clear out the frame time history.
905050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        frame_time_history_.ResetWithSeed(
906050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas            GuessFrameTime(compositor_surfaces_.size()));
907050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        frame_time_backlog_.clear();
908a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        DebugHudData::data.hwc_frame_stats.SkipFrame();
909a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
910a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        continue;
911a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      } else {
912a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        // Make the transition more obvious in systrace when the frame skip
913a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        // happens above.
914a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ATRACE_INT("frame_skip_count", 0);
915a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
916a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
917a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (sleep_time_ns > 0) {
918a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        error = SleepUntil(display_time_est - frame_time_estimate);
919a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
920a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                 strerror(-error));
921050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        if (error == kPostThreadInterrupted)
922050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          continue;
923a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
924a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
925a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
926a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    DebugHudData::data.hwc_frame_stats.AddFrame();
927a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
928a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t frame_start_time = GetSystemClockNs();
929a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
930a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Setup the output buffer for the compositor. This needs to happen before
931a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // you draw with the compositor.
932a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (gpu_layer_ != nullptr) {
933a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
934a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
935a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
936a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Call PostLayers now before performing the GL code for the compositor to
937a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // avoid missing the deadline that can cause the lower-level hwc to get
938a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // permanently backed up.
939a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    PostLayers(layer_config_changed);
940a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
941050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    PostCompositorBuffers();
942a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
943a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (gpu_layer_ != nullptr) {
944a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Note, with scanline racing, this draw is timed along with the post
945a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // layers to finish just in time.
946a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      LocalHandle frame_fence_fd;
947a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
948a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (frame_fence_fd) {
949050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
950a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            "Frame time backlog exceeds capacity");
951050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        frame_time_backlog_.push_back(
952a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            {frame_start_time, std::move(frame_fence_fd)});
953a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
954a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else if (!layer_config_changed) {
955050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
956a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
957a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
958a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    HandlePendingScreenshots();
959a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
960a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
961a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
962050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool HardwareComposer::UpdateLayerConfig() {
963050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
964050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  {
965050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    std::lock_guard<std::mutex> lock(post_thread_mutex_);
966050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!active_surfaces_updated_)
967050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      return false;
968050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    old_display_surfaces = display_surfaces_;
969050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    display_surfaces_ = active_surfaces_;
970050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    active_surfaces_updated_ = false;
971050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
972f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas
9737480c060cb3466d97ec3125d61bbace153f534c8Jin Qian  DebugHudData::data.ResetLayers();
974f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas
975050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Figure out whether we need to update hardware layers. If this surface
976050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // change does not add or remove hardware layers we can avoid display hiccups
977050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // by gracefully updating only the GPU compositor layers.
978050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  int old_gpu_layer_count = 0;
979050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  int new_gpu_layer_count = 0;
980050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  bool hardware_layers_need_update = false;
981050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Look for new hardware layers and count new GPU layers.
982050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  for (const auto& surface : display_surfaces_) {
983050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!(surface->flags() &
984050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
985050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      ++new_gpu_layer_count;
986050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
987050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                       surface) == old_display_surfaces.end())
988050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      // This is a new hardware layer, we need to update.
989050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      hardware_layers_need_update = true;
990050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
991050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Look for deleted hardware layers or compositor layers.
992050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  for (const auto& surface : old_display_surfaces) {
993050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    if (!(surface->flags() &
994050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
995050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      ++old_gpu_layer_count;
996050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
997050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas                       surface) == display_surfaces_.end())
998050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      // This is a deleted hardware layer, we need to update.
999050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      hardware_layers_need_update = true;
1000050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
1001050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Check for compositor hardware layer transition.
1002050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if ((!old_gpu_layer_count && new_gpu_layer_count) ||
1003050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas      (old_gpu_layer_count && !new_gpu_layer_count))
1004050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    hardware_layers_need_update = true;
1005050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
1006050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  // Set the chosen layer order for all surfaces.
1007050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1008050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
1009050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  }
1010050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas
1011a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Update compositor layers.
1012a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  {
1013a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1014a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    compositor_.UpdateSurfaces(display_surfaces_);
1015050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas    compositor_surfaces_.clear();
1016a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1017a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      const auto& surface = display_surfaces_[i];
1018a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (!(surface->flags() &
1019a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
1020050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas        compositor_surfaces_.push_back(surface);
1021a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1022a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1023a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1024a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1025050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  if (!hardware_layers_need_update)
1026a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return true;
1027a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1028a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Update hardware layers.
1029a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1030a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ATRACE_NAME("UpdateLayerConfig_HwLayers");
1031a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1032a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Update the display layers in a non-destructive fashion.
1033a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1034a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Create a map from surface id to hardware layer
1035a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::map<int, Layer*> display_surface_layers;
1036a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1037a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < active_layer_count_; ++i) {
1038a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    auto layer = layers_[i];
1039a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int surface_id = layer->GetSurfaceId();
1040a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1041a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    auto found =
1042a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1043a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                     [surface_id](const auto& surface) {
1044a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                       return surface->surface_id() == surface_id;
1045a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                     });
1046a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1047a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (found != display_surfaces_.end()) {
1048a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display_surface_layers[surface_id] = layer;
1049a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1050a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1051a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1052a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  bool has_gpu_layer = std::any_of(
1053a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display_surfaces_.begin(), display_surfaces_.end(),
1054a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      [](const auto& surface) {
1055a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        return !(surface->flags() &
1056a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1057a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      });
1058a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1059a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (!has_gpu_layer) {
1060a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    gpu_layer_ = nullptr;
1061a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1062a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1063a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1064a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int surface_id = layer->GetSurfaceId();
1065a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (surface_id >= 0) {
1066a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return display_surface_layers.count(surface_id) > 0;
1067a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
1068a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return has_gpu_layer;
1069a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1070a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  };
1071a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1072a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Compress the in-use layers to the top of the list
1073a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  auto part = std::partition(
1074a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1075a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1076a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  size_t new_active_layer_count = part - layers_.begin();
1077a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1078a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Clear any unused layers
1079a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1080a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    layers_[i]->Reset();
1081a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1082a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1083a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  active_layer_count_ = new_active_layer_count;
1084a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1085a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  bool gpu_layer_applied = false;
1086a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1087a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Create/update all of the hardware layers
1088a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1089a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const auto& surface = display_surfaces_[i];
1090a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    bool is_hw_surface =
1091a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1092a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc2_blend_mode_t blending =
1093a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1094a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1095a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    DebugHudData::data.SetLayerInfo(
1096a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        i, surface->width(), surface->height(),
1097a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1098a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1099a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (!is_hw_surface && gpu_layer_applied) {
1100a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      continue;
1101a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1102a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1103a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    Layer* target_layer;
1104a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    bool existing_layer = false;
1105a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1106a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (is_hw_surface) {
1107a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      auto it = display_surface_layers.find(surface->surface_id());
1108a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1109a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (it != display_surface_layers.end()) {
1110a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        target_layer = it->second;
1111a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        existing_layer = true;
1112a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1113a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else if (gpu_layer_ != nullptr) {
1114a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      target_layer = gpu_layer_;
1115a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      existing_layer = true;
1116a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1117a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1118a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (!existing_layer) {
1119a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (active_layer_count_ >= kMaxHardwareLayers) {
1120a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ALOGI("HardwareComposer: More than %d hardware layers requested.",
1121a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko              kMaxHardwareLayers);
1122a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        break;
1123a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      } else {
1124a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        target_layer = layers_[active_layer_count_];
1125a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ++active_layer_count_;
1126a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1127a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1128a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGD_IF(TRACE,
1129a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1130a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               "layer=%zd",
1131a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               surface->surface_id(), i);
1132a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1133a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (is_hw_surface) {
1134a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        target_layer->Setup(surface, blending, display_transform_,
1135a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            HWC2_COMPOSITION_DEVICE, i);
1136a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      } else {
1137a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        gpu_layer_ = target_layer;
1138a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        target_layer->Setup(compositor_.GetBuffer(), blending,
1139a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                            display_transform_, HWC2_COMPOSITION_DEVICE, i);
1140a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1141a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
1142a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGD_IF(TRACE,
1143a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1144a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               "-> layer=%zd",
1145a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko               surface->surface_id(), i);
1146a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1147a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      target_layer->SetBlending(blending);
1148a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      target_layer->SetZOrderIndex(i);
1149a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      target_layer->UpdateLayerSettings();
1150a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1151a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1152a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    gpu_layer_applied = !is_hw_surface;
1153a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1154a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1155a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1156a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           active_layer_count_);
1157a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1158a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return true;
1159a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1160a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1161050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::PostCompositorBuffers() {
1162a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ATRACE_NAME("PostCompositorBuffers");
1163050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas  for (const auto& surface : compositor_surfaces_) {
1164a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    compositor_.PostBuffer(surface);
1165a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1166a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1167a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1168a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::UpdateFrameTimeHistory(
1169a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1170a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1171a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  while (!backlog->empty()) {
1172a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const auto& frame_time_record = backlog->front();
1173a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t end_time = 0;
1174a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1175a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                             fence_info_buffer, &end_time);
1176a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (frame_finished) {
1177a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      int64_t frame_duration = end_time - frame_time_record.start_time;
1178a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      history->AddSample(frame_duration);
1179a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Our backlog is tiny (2 elements), so erasing from the front is ok
1180a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      backlog->erase(backlog->begin());
1181a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
1182a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      break;
1183a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1184a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1185a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1186a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (backlog->size() == static_cast<size_t>(backlog_max)) {
1187a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Yikes, something must've gone wrong if our oldest frame hasn't finished
1188a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // yet. Give up on waiting for it.
1189a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const auto& stale_frame_time_record = backlog->front();
1190a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    int64_t frame_duration =
1191a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        GetSystemClockNs() - stale_frame_time_record.start_time;
1192a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    backlog->erase(backlog->begin());
1193a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    history->AddSample(frame_duration);
1194a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGW("Frame didn't finish after %.1fms",
1195a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          static_cast<double>(frame_duration) / 1000000);
1196a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1197a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1198a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1199a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkobool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1200a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                          FenceInfoBuffer* fence_info_buffer,
1201a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                          int64_t* timestamp) {
1202a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int result = -1;
1203a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int sync_result = sync_wait(frame_fence_fd, 0);
1204a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (sync_result == 0) {
1205a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    result =
1206a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1207a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (result < 0) {
1208a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGE("Failed getting signaled timestamp from fence");
1209a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1210a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  } else if (errno != ETIME) {
1211a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("sync_wait on frame fence failed");
1212a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1213a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  return result >= 0;
1214a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1215a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1216a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HandlePendingScreenshots() {
1217a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Take a screenshot of the requested layer, if available.
1218a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // TODO(eieio): Look into using virtual displays to composite the layer stack
1219a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // into a single output buffer that can be returned to the screenshot clients.
1220a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (active_layer_count_ > 0) {
1221a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (auto screenshot_service = ScreenshotService::GetInstance()) {
1222a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (screenshot_service->IsScreenshotRequestPending()) {
1223a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ATRACE_NAME("screenshot");
1224a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        screenshot_service->TakeIfNeeded(layers_, compositor_);
1225a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1226a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else {
1227a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ALOGW(
1228a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          "HardwareComposer::HandlePendingScreenshots: Failed to get "
1229a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          "screenshot service!");
1230a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1231a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1232a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1233a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1234a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1235a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  vsync_callback_ = callback;
1236a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1237a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1238a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1239a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                  hwc2_display_t /*display*/) {
1240a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // TODO(eieio): implement invalidate callbacks.
1241a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1242a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1243a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1244a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                hwc2_display_t /*display*/,
1245a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                int64_t /*timestamp*/) {
1246a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ATRACE_NAME(__PRETTY_FUNCTION__);
1247a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // Intentionally empty. HWC may require a callback to be set to enable vsync
1248a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // signals. We bypass this callback thread by monitoring the vsync event
1249a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // directly, but signals still need to be enabled.
1250a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1251a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1252a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1253a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                  hwc2_display_t /*display*/,
1254a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                  hwc2_connection_t /*connected*/) {
1255a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // TODO(eieio): implement display hotplug callbacks.
1256a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1257a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
12583cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid HardwareComposer::OnHardwareComposerRefresh() {
12593cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas  // TODO(steventhomas): Handle refresh.
12603cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas}
12613cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas
1262a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::SetBacklightBrightness(int brightness) {
1263a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (backlight_brightness_fd_) {
1264a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    std::array<char, 32> text;
1265a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    const int length = snprintf(text.data(), text.size(), "%d", brightness);
1266a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    write(backlight_brightness_fd_.Get(), text.data(), length);
1267a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1268a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1269a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1270a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoLayer::Layer()
1271a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    : hwc2_hidl_(nullptr),
1272a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      surface_index_(-1),
1273a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      hardware_composer_layer_(0),
1274a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display_metrics_(nullptr),
1275a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      blending_(HWC2_BLEND_MODE_NONE),
1276a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      transform_(HWC_TRANSFORM_NONE),
1277a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      composition_type_(HWC2_COMPOSITION_DEVICE),
1278a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      surface_rect_functions_applied_(false) {}
1279a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1280a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1281a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  hwc2_hidl_ = hwc2_hidl;
1282a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_metrics_ = metrics;
1283a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1284a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1285a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Reset() {
1286a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  const int ret = acquired_buffer_.Release(std::move(release_fence_));
1287a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1288a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           strerror(-ret));
1289a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1290a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1291a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1292a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hardware_composer_layer_ = 0;
1293a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1294a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1295a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_index_ = static_cast<size_t>(-1);
1296a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  blending_ = HWC2_BLEND_MODE_NONE;
1297a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  transform_ = HWC_TRANSFORM_NONE;
1298a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  composition_type_ = HWC2_COMPOSITION_DEVICE;
1299a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  direct_buffer_ = nullptr;
1300a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_ = nullptr;
1301a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  acquire_fence_fd_.Close();
1302a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_rect_functions_applied_ = false;
1303a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1304a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1305a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1306a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                  hwc2_blend_mode_t blending, hwc_transform_t transform,
1307a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                  hwc2_composition_t composition_type, size_t index) {
1308a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  Reset();
1309a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_index_ = index;
1310a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_ = surface;
1311a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  blending_ = blending;
1312a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  transform_ = transform;
1313a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  composition_type_ = composition_type;
1314a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  CommonLayerSetup();
1315a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1316a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1317a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1318a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                  hwc2_blend_mode_t blending, hwc_transform_t transform,
1319a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                  hwc2_composition_t composition_type, size_t z_order) {
1320a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  Reset();
1321a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  surface_index_ = z_order;
1322a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  direct_buffer_ = buffer;
1323a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  blending_ = blending;
1324a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  transform_ = transform;
1325a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  composition_type_ = composition_type;
1326a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  CommonLayerSetup();
1327a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1328a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1329a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1330a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  direct_buffer_ = buffer;
1331a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1332a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1333a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1334a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1335a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1336a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1337a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoIonBuffer* Layer::GetBuffer() {
1338a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (direct_buffer_)
1339a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return direct_buffer_.get();
1340a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  else if (acquired_buffer_.IsAvailable())
1341a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return acquired_buffer_.buffer()->buffer();
1342a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  else
1343a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return nullptr;
1344a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1345a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1346a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::UpdateLayerSettings() {
1347a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (!IsLayerSetup()) {
1348a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1349a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    return;
1350a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1351a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1352a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = HWC2_ERROR_NONE;
1353a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1354a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1355a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1356a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1357a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display, hardware_composer_layer_,
1358a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      (Hwc2::IComposerClient::Composition)composition_type_);
1359a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1360a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           ret);
1361a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1362a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // hardware_composer_layer_,
1363a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //                                    (Hwc2::IComposerClient::Transform)
1364a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //                                    transform_);
1365a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1366a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1367a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1368a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //    hardware_composer_device_, display, hardware_composer_layer_,
1369a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  //    blending_);
1370a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1371a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display, hardware_composer_layer_,
1372a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      (Hwc2::IComposerClient::BlendMode)blending_);
1373a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1374a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1375a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  Hwc2::IComposerClient::Rect display_frame;
1376a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_frame.left = 0;
1377a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_frame.top = 0;
1378a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_frame.right = display_metrics_->width;
1379a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  display_frame.bottom = display_metrics_->height;
1380a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1381a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display, hardware_composer_layer_, display_frame);
1382a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1383a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           ret);
1384a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1385a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1386a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  visible_region[0] = display_frame;
1387a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1388a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      display, hardware_composer_layer_, visible_region);
1389a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1390a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           ret);
1391a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1392a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1393a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                                hardware_composer_layer_, 1.0f);
1394a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1395a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1396a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1397a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                            surface_index_);
1398a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1399a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1400a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1401a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::CommonLayerSetup() {
1402a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1403a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                                 &hardware_composer_layer_);
1404a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1405a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  ALOGE_IF(ret,
1406a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           "HardwareComposer: Failed to create layer on primary display : %d",
1407a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko           ret);
1408a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1409a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  UpdateLayerSettings();
1410a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1411a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1412a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Prepare() {
1413a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int right, bottom;
1414a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  buffer_handle_t handle;
1415a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1416a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (surface_) {
1417a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // Only update the acquired buffer when one is either available or this is
1418a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // the first time through.
1419a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    if (surface_->IsBufferAvailable()) {
1420a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // If we previously set this to a solid color layer to stall for time,
1421a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // revert it to a device layer.
1422a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (acquired_buffer_.IsEmpty() &&
1423a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko          composition_type_ != HWC2_COMPOSITION_DEVICE) {
1424a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        composition_type_ = HWC2_COMPOSITION_DEVICE;
1425a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        hwc2_hidl_->setLayerCompositionType(
1426a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1427a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1428a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1429a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1430a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      DebugHudData::data.AddLayerFrame(surface_index_);
1431a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      acquired_buffer_.Release(std::move(release_fence_));
1432a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      acquired_buffer_ = surface_->AcquireCurrentBuffer();
1433a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1434a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // Basic latency stopgap for when the application misses a frame:
1435a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // If the application recovers on the 2nd or 3rd (etc) frame after
1436a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // missing, this code will skip a frame to catch up by checking if
1437a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // the next frame is also available.
1438a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (surface_->IsBufferAvailable()) {
1439a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        DebugHudData::data.SkipLayerFrame(surface_index_);
1440a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ATRACE_NAME("DropToCatchUp");
1441a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1442a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        acquired_buffer_ = surface_->AcquireCurrentBuffer();
1443a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1444a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1445a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    } else if (acquired_buffer_.IsEmpty()) {
1446a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      // While we are waiting for a buffer, set this to be an empty layer
1447a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1448a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1449a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        hwc2_hidl_->setLayerCompositionType(
1450a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1451a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1452a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1453a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        Hwc2::IComposerClient::Color layer_color = {
1454a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko            0, 0, 0, 0,
1455a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        };
1456a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1457a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                  layer_color);
1458a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      }
1459a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko      return;
1460a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    }
1461a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    right = acquired_buffer_.buffer()->width();
1462a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    bottom = acquired_buffer_.buffer()->height();
1463a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    handle = acquired_buffer_.buffer()->native_handle();
1464a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1465a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  } else {
1466a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai    // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
1467a3613612a1142c3134045f08c30a861ea43288edJiwen 'Steve' Cai    // mechanism to accept distorted layers from VrCore.
1468a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    right = direct_buffer_->width();
1469a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    bottom = direct_buffer_->height();
1470a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    handle = direct_buffer_->handle();
1471a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    acquire_fence_fd_.Close();
1472a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1473a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1474a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  int32_t ret = HWC2_ERROR_NONE;
1475a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1476a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1477a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
147806d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu                                              hardware_composer_layer_, 0,
147906d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu                                              handle,
1480a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                              acquire_fence_fd_.Get());
1481a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1482a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1483a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1484a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1485a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  if (!surface_rect_functions_applied_) {
1486a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    Hwc2::IComposerClient::FRect crop_rect = {
1487a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        0, 0, static_cast<float>(right), static_cast<float>(bottom),
1488a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    };
1489a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1490a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko                                   hardware_composer_layer_, crop_rect);
1491a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1492a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1493a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko             ret);
1494a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1495a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1496a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// it must/cannot be called?
1497a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#ifdef QCOM_BSP
1498a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc_rect_t damage_rect = {
1499a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        0, 0, right, bottom,
1500a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    };
1501a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    hwc_region_t damage = {
1502a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko        1, &damage_rect,
1503a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    };
1504a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // ret = hwc2_funcs_->set_layer_surface_damage(
1505a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    //    hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1506a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    //    hardware_composer_layer_, damage);
1507a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // uses a std::vector as the listing
1508a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1509a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    // hardware_composer_layer_, vector here);
1510a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1511a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1512a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko             ret);
1513a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#endif
1514a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1515a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko    surface_rect_functions_applied_ = true;
1516a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  }
1517a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1518a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1519a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Finish(int release_fence_fd) {
1520a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko  release_fence_.Reset(release_fence_fd);
1521a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}
1522a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1523a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Drop() { acquire_fence_fd_.Close(); }
1524a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko
1525a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}  // namespace dvr
1526a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko}  // namespace android
1527