1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 15 */ 16 17 #include <HwcTrace.h> 18 #include <IDisplayDevice.h> 19 #include <DisplayQuery.h> 20 #include <BufferManager.h> 21 #include <DisplayPlaneManager.h> 22 #include <Hwcomposer.h> 23 #include <VsyncManager.h> 24 25 26 namespace android { 27 namespace intel { 28 29 VsyncManager::VsyncManager(Hwcomposer &hwc) 30 :mHwc(hwc), 31 mInitialized(false), 32 mEnableDynamicVsync(true), 33 mEnabled(false), 34 mVsyncSource(IDisplayDevice::DEVICE_COUNT), 35 mLock() 36 { 37 } 38 39 VsyncManager::~VsyncManager() 40 { 41 WARN_IF_NOT_DEINIT(); 42 } 43 44 bool VsyncManager::initialize() 45 { 46 47 mEnabled = false; 48 mVsyncSource = IDisplayDevice::DEVICE_COUNT; 49 mEnableDynamicVsync = !scUsePrimaryVsyncOnly; 50 mInitialized = true; 51 return true; 52 } 53 54 void VsyncManager::deinitialize() 55 { 56 if (mEnabled) { 57 WTRACE("vsync is still enabled"); 58 } 59 60 mVsyncSource = IDisplayDevice::DEVICE_COUNT; 61 mEnabled = false; 62 mEnableDynamicVsync = !scUsePrimaryVsyncOnly; 63 mInitialized = false; 64 } 65 66 bool VsyncManager::handleVsyncControl(int disp, bool enabled) 67 { 68 Mutex::Autolock l(mLock); 69 70 if (disp != IDisplayDevice::DEVICE_PRIMARY) { 71 WTRACE("vsync control on non-primary device %d", disp); 72 return false; 73 } 74 75 if (mEnabled == enabled) { 76 WTRACE("vsync state %d is not changed", enabled); 77 return true; 78 } 79 80 if (!enabled) { 81 disableVsync(); 82 mEnabled = false; 83 return true; 84 } else { 85 mEnabled = enableVsync(getCandidate()); 86 return mEnabled; 87 } 88 89 return false; 90 } 91 92 void VsyncManager::resetVsyncSource() 93 { 94 Mutex::Autolock l(mLock); 95 96 if (!mEnableDynamicVsync) { 97 ITRACE("dynamic vsync source switch is not supported"); 98 return; 99 } 100 101 if (!mEnabled) { 102 return; 103 } 104 105 int vsyncSource = getCandidate(); 106 if (vsyncSource == mVsyncSource) { 107 return; 108 } 109 110 disableVsync(); 111 enableVsync(vsyncSource); 112 } 113 114 int VsyncManager::getVsyncSource() 115 { 116 return mVsyncSource; 117 } 118 119 void VsyncManager::enableDynamicVsync(bool enable) 120 { 121 Mutex::Autolock l(mLock); 122 if (scUsePrimaryVsyncOnly) { 123 WTRACE("dynamic vsync is not supported"); 124 return; 125 } 126 127 mEnableDynamicVsync = enable; 128 129 if (!mEnabled) { 130 return; 131 } 132 133 int vsyncSource = getCandidate(); 134 if (vsyncSource == mVsyncSource) { 135 return; 136 } 137 138 disableVsync(); 139 enableVsync(vsyncSource); 140 } 141 142 IDisplayDevice* VsyncManager::getDisplayDevice(int dispType ) { 143 return mHwc.getDisplayDevice(dispType); 144 } 145 146 int VsyncManager::getCandidate() 147 { 148 if (!mEnableDynamicVsync) { 149 return IDisplayDevice::DEVICE_PRIMARY; 150 } 151 152 IDisplayDevice *device = NULL; 153 // use HDMI vsync when connected 154 device = getDisplayDevice(IDisplayDevice::DEVICE_EXTERNAL); 155 if (device && device->isConnected()) { 156 return IDisplayDevice::DEVICE_EXTERNAL; 157 } 158 159 // use vsync from virtual display when video extended mode is entered 160 if (Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) { 161 device = getDisplayDevice(IDisplayDevice::DEVICE_VIRTUAL); 162 if (device && device->isConnected()) { 163 return IDisplayDevice::DEVICE_VIRTUAL; 164 } 165 WTRACE("Could not use vsync from secondary device"); 166 } 167 return IDisplayDevice::DEVICE_PRIMARY; 168 } 169 170 bool VsyncManager::enableVsync(int candidate) 171 { 172 if (mVsyncSource != IDisplayDevice::DEVICE_COUNT) { 173 WTRACE("vsync has been enabled on %d", mVsyncSource); 174 return true; 175 } 176 177 IDisplayDevice *device = getDisplayDevice(candidate); 178 if (!device) { 179 ETRACE("invalid vsync source candidate %d", candidate); 180 return false; 181 } 182 183 if (device->vsyncControl(true)) { 184 mVsyncSource = candidate; 185 return true; 186 } 187 188 if (candidate != IDisplayDevice::DEVICE_PRIMARY) { 189 WTRACE("failed to enable vsync on display %d, fall back to primary", candidate); 190 device = getDisplayDevice(IDisplayDevice::DEVICE_PRIMARY); 191 if (device && device->vsyncControl(true)) { 192 mVsyncSource = IDisplayDevice::DEVICE_PRIMARY; 193 return true; 194 } 195 } 196 ETRACE("failed to enable vsync on the primary display"); 197 return false; 198 } 199 200 void VsyncManager::disableVsync() 201 { 202 if (mVsyncSource == IDisplayDevice::DEVICE_COUNT) { 203 WTRACE("vsync has been disabled"); 204 return; 205 } 206 207 IDisplayDevice *device = getDisplayDevice(mVsyncSource); 208 if (device && !device->vsyncControl(false)) { 209 WTRACE("failed to disable vsync on device %d", mVsyncSource); 210 } 211 mVsyncSource = IDisplayDevice::DEVICE_COUNT; 212 } 213 214 } // namespace intel 215 } // namespace android 216 217