1a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include "hardware_composer.h" 2a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <cutils/properties.h> 4a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <cutils/sched_policy.h> 5a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <fcntl.h> 62251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <log/log.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> 142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <time.h> 15a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <unistd.h> 16a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <utils/Trace.h> 17a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 18a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <algorithm> 192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <chrono> 20a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <functional> 21a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <map> 22a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <dvr/dvr_display_types.h> 24a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <dvr/performance_client_api.h> 25a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/clock_ns.h> 262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#include <private/dvr/ion_buffer.h> 27a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#include <private/dvr/pose_client_internal.h> 28a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 29a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkousing android::pdx::LocalHandle; 302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::rpc::EmptyVariant; 312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing android::pdx::rpc::IfAnyOf; 322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakausing namespace std::chrono_literals; 34a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 35a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace android { 36a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace dvr { 37a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 38a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkonamespace { 39a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 40a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// If the number of pending fences goes over this count at the point when we 41a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// are about to submit a new frame to HWC, we will drop the frame. This should 42a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// be a signal that the display driver has begun queuing frames. Note that with 43a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// smart displays (with RAM), the fence is signaled earlier than the next vsync, 44a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// at the point when the DMA to the display completes. Currently we use a smart 45a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// display and the EDS timing coincides with zero pending fences, so this is 0. 46a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconstexpr int kAllowedPendingFenceCount = 0; 47a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Offset before vsync to submit frames to hardware composer. 492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaconstexpr int64_t kFramePostOffsetNs = 4000000; // 4ms 50a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 51a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kBacklightBrightnessSysFile[] = 52a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "/sys/class/leds/lcd-backlight/brightness"; 53a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 54a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kPrimaryDisplayVSyncEventFile[] = 55a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "/sys/class/graphics/fb0/vsync_event"; 56a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 57a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp"; 58a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 59a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoconst char kDvrPerformanceProperty[] = "sys.dvr.performance"; 60a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 614b78832d7fc3cdd13a20587dfee96d1505916213Luke Songconst char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns"; 62a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 63a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Get time offset from a vsync to when the pose for that vsync should be 64a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// predicted out to. For example, if scanout gets halfway through the frame 65a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// at the halfway point between vsyncs, then this could be half the period. 66a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// With global shutter displays, this should be changed to the offset to when 67a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// illumination begins. Low persistence adds a frame of latency, so we predict 68a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// to the center of the next frame. 69a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoinline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) { 70a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return (vsync_period_ns * 150) / 100; 71a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 72a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Attempts to set the scheduler class and partiton for the current thread. 742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Returns true on success or false on failure. 752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakabool SetThreadPolicy(const std::string& scheduler_class, 762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const std::string& partition) { 772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka int error = dvrSetSchedulerClass(0, scheduler_class.c_str()); 782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error < 0) { 792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "SetThreadPolicy: Failed to set scheduler class \"%s\" for " 812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "thread_id=%d: %s", 822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka scheduler_class.c_str(), gettid(), strerror(-error)); 832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return false; 842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = dvrSetCpuPartition(0, partition.c_str()); 862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error < 0) { 872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: " 892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "%s", 902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka partition.c_str(), gettid(), strerror(-error)); 912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return false; 922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return true; 942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 96a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} // anonymous namespace 97a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Layer static data. 992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHwc2::Composer* Layer::hwc2_hidl_; 1002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaconst HWCDisplayMetrics* Layer::display_metrics_; 1012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// HardwareComposer static data; 1032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaconstexpr size_t HardwareComposer::kMaxHardwareLayers; 1042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 105a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoHardwareComposer::HardwareComposer() 1062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka : HardwareComposer(nullptr, RequestDisplayCallback()) {} 107a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHardwareComposer::HardwareComposer( 1092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback) 110016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk : initialized_(false), 111016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk hwc2_hidl_(hwc2_hidl), 1122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka request_display_callback_(request_display_callback), 1132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka callbacks_(new ComposerCallback) {} 114a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 115a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoHardwareComposer::~HardwareComposer(void) { 1162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UpdatePostThreadState(PostThreadState::Quit, true); 1172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (post_thread_.joinable()) 118050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas post_thread_.join(); 119a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 120a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 121016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazykbool HardwareComposer::Initialize() { 122016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk if (initialized_) { 123016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk ALOGE("HardwareComposer::Initialize: already initialized."); 124a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return false; 125a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 126a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error = HWC::Error::None; 128a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 129016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk Hwc2::Config config; 1302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config); 131a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 133016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk ALOGE("HardwareComposer: Failed to get current display config : %d", 134016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk config); 135a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return false; 136a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 137a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = 139016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_); 140a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 142016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk ALOGE( 143016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk "HardwareComposer: Failed to get display attributes for current " 144016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk "configuration : %d", 1452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.value); 146a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return false; 147a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 148a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 149a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGI( 150a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer: primary display attributes: width=%d height=%d " 151a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "vsync_period_ns=%d DPI=%dx%d", 152a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko native_display_metrics_.width, native_display_metrics_.height, 153a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x, 154a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko native_display_metrics_.dpi.y); 155a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 156016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk // Set the display metrics but never use rotation to avoid the long latency of 157016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk // rotation processing in hwc. 158016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk display_transform_ = HWC_TRANSFORM_NONE; 159016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk display_metrics_ = native_display_metrics_; 160016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk 1612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Pass hwc instance and metrics to setup globals for Layer. 1622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_); 1632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 165050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas LOG_ALWAYS_FATAL_IF( 1662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka !post_thread_event_fd_, 167050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer: Failed to create interrupt event fd : %s", 168050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(errno)); 169050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 170050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas post_thread_ = std::thread(&HardwareComposer::PostThread, this); 171050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 172016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk initialized_ = true; 173016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk 174016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk return initialized_; 175016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk} 176016e5e3ca751de7e86731349985d1eaf7c072515Stephen Kiazyk 177050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::Enable() { 1782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UpdatePostThreadState(PostThreadState::Suspended, false); 179050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas} 1807480c060cb3466d97ec3125d61bbace153f534c8Jin Qian 181050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::Disable() { 1822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UpdatePostThreadState(PostThreadState::Suspended, true); 1832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka} 1842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Update the post thread quiescent state based on idle and suspended inputs. 1862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid HardwareComposer::UpdatePostThreadState(PostThreadStateType state, 1872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka bool suspend) { 188050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas std::unique_lock<std::mutex> lock(post_thread_mutex_); 1892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Update the votes in the state variable before evaluating the effective 1912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // quiescent state. Any bits set in post_thread_state_ indicate that the post 1922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // thread should be suspended. 1932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (suspend) { 1942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_state_ |= state; 1952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 1962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_state_ &= ~state; 1972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 1982251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 1992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const bool quit = post_thread_state_ & PostThreadState::Quit; 2002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const bool effective_suspend = post_thread_state_ != PostThreadState::Active; 2012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (quit) { 2022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_quiescent_ = true; 2032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka eventfd_write(post_thread_event_fd_.Get(), 1); 2042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_wait_.notify_one(); 2052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else if (effective_suspend && !post_thread_quiescent_) { 2062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_quiescent_ = true; 2072251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka eventfd_write(post_thread_event_fd_.Get(), 1); 2082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else if (!effective_suspend && post_thread_quiescent_) { 2092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_quiescent_ = false; 2102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka eventfd_t value; 2112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka eventfd_read(post_thread_event_fd_.Get(), &value); 2122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_wait_.notify_one(); 213050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 2147480c060cb3466d97ec3125d61bbace153f534c8Jin Qian 2152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Wait until the post thread is in the requested state. 2162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_ready_.wait(lock, [this, effective_suspend] { 2172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return effective_suspend != post_thread_resumed_; 2182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 219050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas} 220a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 221050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::OnPostThreadResumed() { 2220af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas hwc2_hidl_->resetCommands(); 2230af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas 224a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Connect to pose service. 225a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko pose_client_ = dvrPoseCreate(); 226a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client"); 227a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // HIDL HWC seems to have an internal race condition. If we submit a frame too 2292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // soon after turning on VSync we don't get any VSync signals. Give poor HWC 2302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // implementations a chance to enable VSync before we continue. 2312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka EnableVsync(false); 2322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::this_thread::sleep_for(100ms); 233050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas EnableVsync(true); 2342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::this_thread::sleep_for(100ms); 235a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 236050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // TODO(skiazyk): We need to do something about accessing this directly, 237050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // supposedly there is a backlight service on the way. 238050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // TODO(steventhomas): When we change the backlight setting, will surface 239050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // flinger (or something else) set it back to its original value once we give 240050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // control of the display back to surface flinger? 241050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas SetBacklightBrightness(255); 242282a5ed48f64e4010f97ca4077e3bd4b54ba3268Steven Thomas 243050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Trigger target-specific performance mode change. 244050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas property_set(kDvrPerformanceProperty, "performance"); 245a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 246a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 247050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::OnPostThreadPaused() { 248a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko retire_fence_fds_.clear(); 2492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display_surfaces_.clear(); 250a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 251a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t i = 0; i < kMaxHardwareLayers; ++i) { 2522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[i].Reset(); 253a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 254a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko active_layer_count_ = 0; 255a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 256050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (pose_client_) { 257a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko dvrPoseDestroy(pose_client_); 258050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas pose_client_ = nullptr; 259050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 260f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas 261050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas EnableVsync(false); 262050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 2630af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas hwc2_hidl_->resetCommands(); 2640af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas 265050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Trigger target-specific performance mode change. 266050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas property_set(kDvrPerformanceProperty, "idle"); 267a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 268a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHWC::Error HardwareComposer::Validate(hwc2_display_t display) { 270a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko uint32_t num_types; 271a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko uint32_t num_requests; 2722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error = 2732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->validateDisplay(display, &num_types, &num_requests); 274a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 275a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (error == HWC2_ERROR_HAS_CHANGES) { 276a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // TODO(skiazyk): We might need to inspect the requested changes first, but 277a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // so far it seems like we shouldn't ever hit a bad state. 278a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_, 279a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // display); 2802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->acceptDisplayChanges(display); 281a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 282a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 283a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return error; 284a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 285a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 286a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint32_t HardwareComposer::EnableVsync(bool enabled) { 287a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return (int32_t)hwc2_hidl_->setVsyncEnabled( 288a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko HWC_DISPLAY_PRIMARY, 289a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE 290a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko : HWC2_VSYNC_DISABLE)); 291a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 292a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 2932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHWC::Error HardwareComposer::Present(hwc2_display_t display) { 294a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int32_t present_fence; 2952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence); 296a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 297a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // According to the documentation, this fence is signaled at the time of 298a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // vsync/DMA for physical displays. 2992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error == HWC::Error::None) { 300a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_INT("HardwareComposer: VsyncFence", present_fence); 301a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko retire_fence_fds_.emplace_back(present_fence); 302a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } else { 303a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_INT("HardwareComposer: PresentResult", error); 304a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 305a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 306a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return error; 307a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 308a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display, 3102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_config_t config, 3112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_attribute_t attribute, 3122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka int32_t* out_value) const { 3132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return hwc2_hidl_->getDisplayAttribute( 314a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value); 315a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 316a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey TabakaHWC::Error HardwareComposer::GetDisplayMetrics( 318a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_display_t display, hwc2_config_t config, 319a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko HWCDisplayMetrics* out_metrics) const { 3202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error; 321a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH, 3232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_metrics->width); 3242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 3262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s", 3272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return error; 329a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 330a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT, 3322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_metrics->height); 3332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 3352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s", 3362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return error; 338a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 339a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD, 3412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_metrics->vsync_period_ns); 3422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 3442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s", 3452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return error; 347a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 348a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X, 3502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_metrics->dpi.x); 3512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 3532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s", 3542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return error; 356a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 357a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y, 3592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_metrics->dpi.y); 3602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 3622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s", 3632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return error; 365a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 366a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return HWC::Error::None; 368a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 369a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakastd::string HardwareComposer::Dump() { return hwc2_hidl_->dumpDebugInfo(); } 371a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid HardwareComposer::PostLayers() { 373a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME("HardwareComposer::PostLayers"); 374a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 375a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Setup the hardware composer layers with current buffers. 376a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t i = 0; i < active_layer_count_; i++) { 3772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[i].Prepare(); 378a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 379a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 3802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error = Validate(HWC_DISPLAY_PRIMARY); 3812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 3822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE("HardwareComposer::PostLayers: Validate failed: %s", 3832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 3840af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas return; 3850af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas } 3860af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas 387a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Now that we have taken in a frame from the application, we have a chance 388a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // to drop the frame before passing the frame along to HWC. 389a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // If the display driver has become backed up, we detect it here and then 390a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // react by skipping this frame to catch up latency. 391a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko while (!retire_fence_fds_.empty() && 392a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko (!retire_fence_fds_.front() || 393a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) { 394a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // There are only 2 fences in here, no performance problem to shift the 395a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // array of ints. 396a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko retire_fence_fds_.erase(retire_fence_fds_.begin()); 397a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 398a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 399a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const bool is_frame_pending = IsFramePendingInDriver(); 400a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const bool is_fence_pending = 401a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko retire_fence_fds_.size() > kAllowedPendingFenceCount; 402a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 403a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (is_fence_pending || is_frame_pending) { 404a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_INT("frame_skip_count", ++frame_skip_count_); 405a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 406a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame"); 407a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGW_IF(is_fence_pending, 408a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "Warning: dropping a frame to catch up with HWC (pending = %zd)", 409a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko retire_fence_fds_.size()); 410a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 411a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t i = 0; i < active_layer_count_; i++) { 4122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[i].Drop(); 413a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 414a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return; 415a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } else { 416a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Make the transition more obvious in systrace when the frame skip happens 417a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // above. 418a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_INT("frame_skip_count", 0); 419a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 420a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 421a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#if TRACE 422a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t i = 0; i < active_layer_count_; i++) 4232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGI("HardwareComposer::PostLayers: layer=%zu composition=%s", i, 4242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[i].GetCompositionType().to_string().c_str()); 425a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko#endif 426a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = Present(HWC_DISPLAY_PRIMARY); 4282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (error != HWC::Error::None) { 4292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE("HardwareComposer::PostLayers: Present failed: %s", 4302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 431a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return; 432a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 433a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 434a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::vector<Hwc2::Layer> out_layers; 435a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::vector<int> out_fences; 4362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers, 4372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &out_fences); 4382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 4392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::PostLayers: Failed to get release fences: %s", 4402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 441a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 442a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Perform post-frame bookkeeping. Unused layers are a no-op. 4432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka uint32_t num_elements = out_layers.size(); 444a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t i = 0; i < num_elements; ++i) { 445a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko for (size_t j = 0; j < active_layer_count_; ++j) { 4462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (layers_[j].GetLayerHandle() == out_layers[i]) { 4472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[j].Finish(out_fences[i]); 448a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 449a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 450a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 451a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 452a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 453050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasvoid HardwareComposer::SetDisplaySurfaces( 4542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) { 455a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd", 456a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko surfaces.size()); 4572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const bool display_idle = surfaces.size() == 0; 4582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka { 4592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::unique_lock<std::mutex> lock(post_thread_mutex_); 4602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka pending_surfaces_ = std::move(surfaces); 4612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 4622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 4632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Set idle state based on whether there are any surfaces to handle. 4642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka UpdatePostThreadState(PostThreadState::Idle, display_idle); 4652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 4662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // XXX: TEMPORARY 4672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Request control of the display based on whether there are any surfaces to 4682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // handle. This callback sets the post thread active state once the transition 4692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // is complete in SurfaceFlinger. 4702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // TODO(eieio): Unify the control signal used to move SurfaceFlinger into VR 4712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // mode. Currently this is hooked up to persistent VR mode, but perhaps this 4722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // makes more sense to control it from VrCore, which could in turn base its 4732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // decision on persistent VR mode. 4742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (request_display_callback_) 4752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka request_display_callback_(!display_idle); 476050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas} 477a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 4782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakaint HardwareComposer::PostThreadPollInterruptible( 4792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const pdx::LocalHandle& event_fd, int requested_events) { 480050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas pollfd pfd[2] = { 481050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas { 4822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka .fd = event_fd.Get(), 48366747c180e456cc762821c61a75a17bee03a4cf9Steven Thomas .events = static_cast<short>(requested_events), 48466747c180e456cc762821c61a75a17bee03a4cf9Steven Thomas .revents = 0, 485050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas }, 486050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas { 4872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka .fd = post_thread_event_fd_.Get(), 488050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas .events = POLLPRI | POLLIN, 489050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas .revents = 0, 490050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas }, 491050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas }; 492050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas int ret, error; 493050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas do { 494050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ret = poll(pfd, 2, -1); 495050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas error = errno; 496050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGW_IF(ret < 0, 497050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer::PostThreadPollInterruptible: Error during " 498050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "poll(): %s (%d)", 499050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(error), error); 500050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } while (ret < 0 && error == EINTR); 5017480c060cb3466d97ec3125d61bbace153f534c8Jin Qian 502050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (ret < 0) { 503050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return -error; 504050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } else if (pfd[0].revents != 0) { 505050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return 0; 506050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } else if (pfd[1].revents != 0) { 507050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGI("VrHwcPost thread interrupted"); 508050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return kPostThreadInterrupted; 509050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } else { 510050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return 0; 5117480c060cb3466d97ec3125d61bbace153f534c8Jin Qian } 512a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 513a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 514a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Reads the value of the display driver wait_pingpong state. Returns 0 or 1 515a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// (the value of the state) on success or a negative error otherwise. 516a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a 517a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually. 518a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::ReadWaitPPState() { 519a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Gracefully handle when the kernel does not support this feature. 520a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (!primary_display_wait_pp_fd_) 521a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return 0; 522a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 523a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int wait_pp_fd = primary_display_wait_pp_fd_.Get(); 524a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int ret, error; 525a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 526a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ret = lseek(wait_pp_fd, 0, SEEK_SET); 527a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 528a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = errno; 529a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s", 530a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 531a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 532a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 533a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 534a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko char data = -1; 535a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ret = read(wait_pp_fd, &data, sizeof(data)); 536a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 537a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = errno; 538a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s", 539a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 540a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 541a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 542a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 543a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko switch (data) { 544a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko case '0': 545a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return 0; 546a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko case '1': 547a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return 1; 548a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko default: 549a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE( 550a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d", 551a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko data); 552a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -EINVAL; 553a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 554a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 555a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 556a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Reads the timestamp of the last vsync from the display driver. 557a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a 558a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually. 559a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) { 560a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int event_fd = primary_display_vsync_event_fd_.Get(); 561a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int ret, error; 562a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 563a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // The driver returns data in the form "VSYNC=<timestamp ns>". 564a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::array<char, 32> data; 565a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko data.fill('\0'); 566a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 567a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Seek back to the beginning of the event file. 568a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ret = lseek(event_fd, 0, SEEK_SET); 569a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 570a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = errno; 571a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE( 572a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: " 573a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "%s", 574a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 575a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 576a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 577a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 578a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Read the vsync event timestamp. 579a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ret = read(event_fd, data.data(), data.size()); 580a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 581a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = errno; 582a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE_IF( 583a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error != EAGAIN, 584a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: " 585a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "%s", 586a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 587a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 588a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 589a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 590a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ret = sscanf(data.data(), "VSYNC=%" PRIu64, 591a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko reinterpret_cast<uint64_t*>(timestamp)); 592a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 593a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = errno; 594a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE( 595a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: " 596a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "%s", 597a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 598a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 599a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 600a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 601a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return 0; 602a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 603a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 604a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Blocks until the next vsync event is signaled by the display driver. 605a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a 606a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually. 607050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasint HardwareComposer::BlockUntilVSync() { 6082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Vsync is signaled by POLLPRI on the fb vsync node. 6092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI); 610a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 611a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 612a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// Waits for the next vsync and returns the timestamp of the vsync event. If 613a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// vsync already passed since the last call, returns the latest vsync timestamp 614a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// instead of blocking. This method updates the last_vsync_timeout_ in the 615a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// process. 616a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// 617a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// TODO(eieio): This is pretty driver specific, this should be moved to a 618a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko// separate class eventually. 619a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::WaitForVSync(int64_t* timestamp) { 620a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int error; 621a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 622a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Get the current timestamp and decide what to do. 623a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko while (true) { 624a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int64_t current_vsync_timestamp; 625a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error = ReadVSyncTimestamp(¤t_vsync_timestamp); 626a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (error < 0 && error != -EAGAIN) 627a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return error; 628a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 629a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (error == -EAGAIN) { 630a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Vsync was turned off, wait for the next vsync event. 631050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas error = BlockUntilVSync(); 632050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (error < 0 || error == kPostThreadInterrupted) 633a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return error; 634a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 635a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Try again to get the timestamp for this new vsync interval. 636a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko continue; 637a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 638a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 639a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Check that we advanced to a later vsync interval. 640a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) { 641a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko *timestamp = last_vsync_timestamp_ = current_vsync_timestamp; 642a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return 0; 643a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 644a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 645a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // See how close we are to the next expected vsync. If we're within 1ms, 646a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // sleep for 1ms and try again. 647a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 6482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int64_t threshold_ns = 1000000; // 1ms 649a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 650a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame; 651a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs(); 652a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 653a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (distance_to_vsync_est > threshold_ns) { 654a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Wait for vsync event notification. 655050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas error = BlockUntilVSync(); 656050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (error < 0 || error == kPostThreadInterrupted) 657a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return error; 658a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } else { 659050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Sleep for a short time (1 millisecond) before retrying. 6602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = SleepUntil(GetSystemClockNs() + threshold_ns); 661050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (error < 0 || error == kPostThreadInterrupted) 662050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return error; 663a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 664a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 665a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 666a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 667a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkoint HardwareComposer::SleepUntil(int64_t wakeup_timestamp) { 668a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int timer_fd = vsync_sleep_timer_fd_.Get(); 669a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const itimerspec wakeup_itimerspec = { 670a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko .it_interval = {.tv_sec = 0, .tv_nsec = 0}, 671a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko .it_value = NsToTimespec(wakeup_timestamp), 672a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko }; 673a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int ret = 674a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr); 675a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int error = errno; 676a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (ret < 0) { 677a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s", 678a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(error)); 679a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return -error; 680a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 681a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 6822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN); 683a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 684a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 685a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::PostThread() { 686a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // NOLINTNEXTLINE(runtime/int) 687050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0); 688a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 6892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Set the scheduler to SCHED_FIFO with high priority. If this fails here 6902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // there may have been a startup timing issue between this thread and 6912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // performanced. Try again later when this thread becomes active. 6922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka bool thread_policy_setup = 6932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SetThreadPolicy("graphics:high", "/system/performance"); 694a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 695050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas#if ENABLE_BACKLIGHT_BRIGHTNESS 696050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // TODO(hendrikw): This isn't required at the moment. It's possible that there 697050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // is another method to access this when needed. 698050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Open the backlight brightness control sysfs node. 699050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR); 700050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGW_IF(!backlight_brightness_fd_, 701050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer: Failed to open backlight brightness control: %s", 702050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(errno)); 7032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka#endif // ENABLE_BACKLIGHT_BRIGHTNESS 704f43d13e4e35ae7d3cdafc4b97c819669d42cef78Steven Thomas 705050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Open the vsync event node for the primary display. 706050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // TODO(eieio): Move this into a platform-specific class. 707050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas primary_display_vsync_event_fd_ = 708050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY); 709050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGE_IF(!primary_display_vsync_event_fd_, 710050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer: Failed to open vsync event node for primary " 711050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "display: %s", 712050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(errno)); 713050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 714050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Open the wait pingpong status node for the primary display. 715050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // TODO(eieio): Move this into a platform-specific class. 716050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas primary_display_wait_pp_fd_ = 717050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY); 718050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas ALOGW_IF( 719050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas !primary_display_wait_pp_fd_, 720050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer: Failed to open wait_pp node for primary display: %s", 721050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(errno)); 722050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 723050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas // Create a timerfd based on CLOCK_MONOTINIC. 724050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0)); 725050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas LOG_ALWAYS_FATAL_IF( 726050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas !vsync_sleep_timer_fd_, 727050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas "HardwareComposer: Failed to create vsync sleep timerfd: %s", 728050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas strerror(errno)); 729a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 730a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int64_t ns_per_frame = display_metrics_.vsync_period_ns; 731a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame); 732a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 733a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // TODO(jbates) Query vblank time from device, when such an API is available. 734a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // This value (6.3%) was measured on A00 in low persistence mode. 735a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int64_t vblank_ns = ns_per_frame * 63 / 1000; 736a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2; 737a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 738a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Check property for overriding right eye offset value. 739a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko right_eye_photon_offset_ns = 740a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns); 741a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 742050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas bool was_running = false; 743050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 744a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko while (1) { 745a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME("HardwareComposer::PostThread"); 746a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 7472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka while (post_thread_quiescent_) { 748050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas std::unique_lock<std::mutex> lock(post_thread_mutex_); 7492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGI("HardwareComposer::PostThread: Entering quiescent state."); 7502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Tear down resources. 7522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka OnPostThreadPaused(); 7532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka was_running = false; 7552251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_resumed_ = false; 7562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_ready_.notify_all(); 7572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (post_thread_state_ & PostThreadState::Quit) { 7592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGI("HardwareComposer::PostThread: Quitting."); 7602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return; 761282a5ed48f64e4010f97ca4077e3bd4b54ba3268Steven Thomas } 7622251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7632251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; }); 7642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_resumed_ = true; 7662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka post_thread_ready_.notify_all(); 7672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGI("HardwareComposer::PostThread: Exiting quiescent state."); 769050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas } 770050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 771050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (!was_running) { 7722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Setup resources. 773050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas OnPostThreadResumed(); 774050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas was_running = true; 7752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 7762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Try to setup the scheduler policy if it failed during startup. Only 7772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // attempt to do this on transitions from inactive to active to avoid 7782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // spamming the system with RPCs and log messages. 7792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!thread_policy_setup) { 7802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka thread_policy_setup = 7812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka SetThreadPolicy("graphics:high", "/system/performance"); 7822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 783a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 784a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 785a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int64_t vsync_timestamp = 0; 786a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko { 787a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::array<char, 128> buf; 788a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|", 789a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko vsync_count_ + 1); 790a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME(buf.data()); 791a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 7922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int error = WaitForVSync(&vsync_timestamp); 793a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE_IF( 794a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko error < 0, 795a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko "HardwareComposer::PostThread: Failed to wait for vsync event: %s", 796a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(-error)); 797a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Don't bother processing this frame if a pause was requested 798050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas if (error == kPostThreadInterrupted) 799a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko continue; 800a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 801a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 802a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ++vsync_count_; 803a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 804a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (pose_client_) { 805a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Signal the pose service with vsync info. 806a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Display timestamp is in the middle of scanout. 807a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko privateDvrPoseNotifyVsync(pose_client_, vsync_count_, 808a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko vsync_timestamp + photon_offset_ns, 809a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ns_per_frame, right_eye_photon_offset_ns); 810a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 811a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const bool layer_config_changed = UpdateLayerConfig(); 813a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 814a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Signal all of the vsync clients. Because absolute time is used for the 815a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // wakeup time below, this can take a little time if necessary. 816a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (vsync_callback_) 8172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, 8182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka /*frame_time_estimate*/ 0, vsync_count_); 819a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 820a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko { 8212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Sleep until shortly before vsync. 822a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME("sleep"); 823a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame; 8252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int64_t now_ns = GetSystemClockNs(); 8262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int64_t sleep_time_ns = 8272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display_time_est_ns - now_ns - kFramePostOffsetNs; 8282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const int64_t wakeup_time_ns = display_time_est_ns - kFramePostOffsetNs; 829a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 830a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_INT64("sleep_time_ns", sleep_time_ns); 831a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (sleep_time_ns > 0) { 8322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka int error = SleepUntil(wakeup_time_ns); 833a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s", 834a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko strerror(-error)); 8350af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas if (error == kPostThreadInterrupted) { 8360af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas if (layer_config_changed) { 8370af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas // If the layer config changed we need to validateDisplay() even if 8380af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas // we're going to drop the frame, to flush the Composer object's 8390af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas // internal command buffer and apply our layer changes. 8400af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas Validate(HWC_DISPLAY_PRIMARY); 8410af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas } 842050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas continue; 8430af4b9f88a48a6ecc705b4a8cec3d3ba24c53eadSteven Thomas } 844a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 845a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 846a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka PostLayers(); 848a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 849a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 850a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// Checks for changes in the surface stack and updates the layer config to 8522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka// accomodate the new stack. 853050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomasbool HardwareComposer::UpdateLayerConfig() { 8542251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces; 855050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas { 8562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::unique_lock<std::mutex> lock(post_thread_mutex_); 8572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (pending_surfaces_.empty()) 858050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas return false; 859050b2c83304bd16ec3a838da08b6ba6acf6a3af4Steven Thomas 8602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surfaces = std::move(pending_surfaces_); 861a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 862a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 863a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME("UpdateLayerConfig_HwLayers"); 864a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display_surfaces_.clear(); 866a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8672251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Layer* target_layer; 8682251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka size_t layer_index; 8692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka for (layer_index = 0; 8702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layer_index < std::min(surfaces.size(), kMaxHardwareLayers); 8712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layer_index++) { 8722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // The bottom layer is opaque, other layers blend. 8732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::BlendMode blending = 8742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage; 8752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[layer_index].Setup(surfaces[layer_index], blending, 8762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display_transform_, HWC::Composition::Device, 8772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layer_index); 8782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display_surfaces_.push_back(surfaces[layer_index]); 879a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 880a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Clear unused layers. 8822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka for (size_t i = layer_index; i < kMaxHardwareLayers; i++) 8832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layers_[i].Reset(); 884a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka active_layer_count_ = layer_index; 886a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers", 887a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko active_layer_count_); 888a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Any surfaces left over could not be assigned a hardware layer and will 8902251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // not be displayed. 8912251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGW_IF(surfaces.size() != display_surfaces_.size(), 8922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::UpdateLayerConfig: More surfaces than layers: " 8932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "pending_surfaces=%zu display_surfaces=%zu", 8942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surfaces.size(), display_surfaces_.size()); 895a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 8962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return true; 897a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 898a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 899a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::SetVSyncCallback(VSyncCallback callback) { 900a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko vsync_callback_ = callback; 901a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 902a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 903a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/, 904a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_display_t /*display*/) { 905a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // TODO(eieio): implement invalidate callbacks. 906a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 907a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 908a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/, 909a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_display_t /*display*/, 910a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int64_t /*timestamp*/) { 911a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko ATRACE_NAME(__PRETTY_FUNCTION__); 912a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // Intentionally empty. HWC may require a callback to be set to enable vsync 913a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // signals. We bypass this callback thread by monitoring the vsync event 914a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // directly, but signals still need to be enabled. 915a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 916a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 917a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/, 918a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_display_t /*display*/, 919a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_connection_t /*connected*/) { 920a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko // TODO(eieio): implement display hotplug callbacks. 921a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 922a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9233cfac28462910d3f976aebac54ac7301aca7e434Steven Thomasvoid HardwareComposer::OnHardwareComposerRefresh() { 9243cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas // TODO(steventhomas): Handle refresh. 9253cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas} 9263cfac28462910d3f976aebac54ac7301aca7e434Steven Thomas 927a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid HardwareComposer::SetBacklightBrightness(int brightness) { 928a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (backlight_brightness_fd_) { 929a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko std::array<char, 32> text; 930a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko const int length = snprintf(text.data(), text.size(), "%d", brightness); 931a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko write(backlight_brightness_fd_.Get(), text.data(), length); 932a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 933a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 934a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl, 9362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const HWCDisplayMetrics* metrics) { 937a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_hidl_ = hwc2_hidl; 938a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko display_metrics_ = metrics; 939a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 940a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 941a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Reset() { 942a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (hwc2_hidl_ != nullptr && hardware_composer_layer_) { 943a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_); 944a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hardware_composer_layer_ = 0; 945a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 946a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka z_order_ = 0; 9482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka blending_ = HWC::BlendMode::None; 9492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka transform_ = HWC::Transform::None; 9502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_ = HWC::Composition::Invalid; 9512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka target_composition_type_ = composition_type_; 9522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka source_ = EmptyVariant{}; 9532251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka acquire_fence_.Close(); 954a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko surface_rect_functions_applied_ = false; 955a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 956a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface, 9582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::BlendMode blending, HWC::Transform transform, 9592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Composition composition_type, size_t z_order) { 960a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko Reset(); 9612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka z_order_ = z_order; 962a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko blending_ = blending; 963a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko transform_ = transform; 9642251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_ = HWC::Composition::Invalid; 9652251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka target_composition_type_ = composition_type; 9662251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka source_ = SourceSurface{surface}; 967a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko CommonLayerSetup(); 968a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 969a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 970a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Setup(const std::shared_ptr<IonBuffer>& buffer, 9712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::BlendMode blending, HWC::Transform transform, 9722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Composition composition_type, size_t z_order) { 973a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko Reset(); 9742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka z_order_ = z_order; 975a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko blending_ = blending; 976a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko transform_ = transform; 9772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_ = HWC::Composition::Invalid; 9782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka target_composition_type_ = composition_type; 9792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka source_ = SourceBuffer{buffer}; 980a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko CommonLayerSetup(); 981a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 982a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) { 9842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (source_.is<SourceBuffer>()) 9852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::get<SourceBuffer>(source_) = {buffer}; 986a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 987a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 9882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; } 9892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::SetZOrder(size_t z_order) { z_order_ = z_order; } 990a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 991a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex VakulenkoIonBuffer* Layer::GetBuffer() { 9922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka struct Visitor { 9932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); } 9942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); } 9952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka IonBuffer* operator()(EmptyVariant) { return nullptr; } 9962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }; 9972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka return source_.Visit(Visitor{}); 998a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 999a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1000a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::UpdateLayerSettings() { 1001a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko if (!IsLayerSetup()) { 10022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE( 10032251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update " 10042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "unused Layer!"); 1005a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko return; 1006a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 1007a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 10082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error; 1009a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko hwc2_display_t display = HWC_DISPLAY_PRIMARY; 1010a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 10112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerCompositionType( 1012a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko display, hardware_composer_layer_, 10132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_.cast<Hwc2::IComposerClient::Composition>()); 10142251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF( 10152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error != HWC::Error::None, 10162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting layer composition type: %s", 10172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 10182251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerBlendMode( 1020a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko display, hardware_composer_layer_, 10212251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka blending_.cast<Hwc2::IComposerClient::BlendMode>()); 10222251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 10232251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting layer blend mode: %s", 10242251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 10252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // TODO(eieio): Use surface attributes or some other mechanism to control 10272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // the layer display frame. 10282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerDisplayFrame( 10292251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display, hardware_composer_layer_, 10302251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka {0, 0, display_metrics_->width, display_metrics_->height}); 10312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 10322251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting layer display frame: %s", 10332251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 10342251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10352251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerVisibleRegion( 10362251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka display, hardware_composer_layer_, 10372251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka {{0, 0, display_metrics_->width, display_metrics_->height}}); 10382251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 10392251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting layer visible region: %s", 10402251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 10412251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10422251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = 10432251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f); 10442251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 10452251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s", 10462251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 10472251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10482251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = 10492251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_); 10502251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 10512251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::UpdateLayerSettings: Error setting z_ order: %s", 10522251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 1053a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 1054a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1055a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::CommonLayerSetup() { 10562251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error = 10572251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_); 10582251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF( 10592251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error != HWC::Error::None, 10602251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::CommonLayerSetup: Failed to create layer on primary display: %s", 10612251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 1062a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko UpdateLayerSettings(); 1063a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 1064a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1065a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Prepare() { 1066a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko int right, bottom; 10671f42e3a02c4f9a1ba1916a2f0e47082bedb73e41Daniel Nicoara sp<GraphicBuffer> handle; 1068a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 10692251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // Acquire the next buffer according to the type of source. 10702251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) { 10712251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka std::tie(right, bottom, handle, acquire_fence_) = source.Acquire(); 10722251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 10732251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka 10742251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // When a layer is first setup there may be some time before the first buffer 10752251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // arrives. Setup the HWC layer as a solid color to stall for time until the 10762251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // first buffer arrives. Once the first buffer arrives there will always be a 10772251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // buffer for the frame even if it is old. 10782251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!handle.get()) { 10792251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (composition_type_ == HWC::Composition::Invalid) { 10802251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_ = HWC::Composition::SolidColor; 10812251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->setLayerCompositionType( 10822251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 10832251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_.cast<Hwc2::IComposerClient::Composition>()); 10842251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0}; 10852251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 10862251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka layer_color); 10872251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } else { 10882251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // The composition type is already set. Nothing else to do until a 10892251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka // buffer arrives. 1090a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 1091a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } else { 10922251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (composition_type_ != target_composition_type_) { 10932251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_ = target_composition_type_; 10942251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hwc2_hidl_->setLayerCompositionType( 10952251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC_DISPLAY_PRIMARY, hardware_composer_layer_, 10962251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka composition_type_.cast<Hwc2::IComposerClient::Composition>()); 10972251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 1098a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 10992251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka HWC::Error error{HWC::Error::None}; 11002251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY, 11012251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hardware_composer_layer_, 0, handle, 11022251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka acquire_fence_.Get()); 1103a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11042251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 11052251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::Prepare: Error setting layer buffer: %s", 11062251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 1107a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11082251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka if (!surface_rect_functions_applied_) { 11092251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const float float_right = right; 11102251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka const float float_bottom = bottom; 11112251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY, 11122251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka hardware_composer_layer_, 11132251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka {0, 0, float_right, float_bottom}); 1114a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11152251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka ALOGE_IF(error != HWC::Error::None, 11162251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka "Layer::Prepare: Error setting layer source crop: %s", 11172251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka error.to_string().c_str()); 1118a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11192251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka surface_rect_functions_applied_ = true; 11202251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka } 1121a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko } 1122a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 1123a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1124a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenkovoid Layer::Finish(int release_fence_fd) { 11252251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka IfAnyOf<SourceSurface, SourceBuffer>::Call( 11262251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka &source_, [release_fence_fd](auto& source) { 11272251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka source.Finish(LocalHandle(release_fence_fd)); 11282251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabaka }); 1129a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} 1130a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 11312251d822dac2a96aad4184a6fdc2690f0a58af7cCorey Tabakavoid Layer::Drop() { acquire_fence_.Close(); } 1132a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko 1133a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} // namespace dvr 1134a8a92784bc5f6a50ce00311c6161fbcfc0898c5aAlex Vakulenko} // namespace android 1135