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(¤t_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