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 #ifdef INTEL_WIDI_MERRIFIELD 160 // use vsync from virtual display when video extended mode is entered 161 if (Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) { 162 device = getDisplayDevice(IDisplayDevice::DEVICE_VIRTUAL); 163 if (device && device->isConnected()) { 164 return IDisplayDevice::DEVICE_VIRTUAL; 165 } 166 WTRACE("Could not use vsync from secondary device"); 167 } 168 #endif 169 return IDisplayDevice::DEVICE_PRIMARY; 170 } 171 172 bool VsyncManager::enableVsync(int candidate) 173 { 174 if (mVsyncSource != IDisplayDevice::DEVICE_COUNT) { 175 WTRACE("vsync has been enabled on %d", mVsyncSource); 176 return true; 177 } 178 179 IDisplayDevice *device = getDisplayDevice(candidate); 180 if (!device) { 181 ETRACE("invalid vsync source candidate %d", candidate); 182 return false; 183 } 184 185 if (device->vsyncControl(true)) { 186 mVsyncSource = candidate; 187 return true; 188 } 189 190 if (candidate != IDisplayDevice::DEVICE_PRIMARY) { 191 WTRACE("failed to enable vsync on display %d, fall back to primary", candidate); 192 device = getDisplayDevice(IDisplayDevice::DEVICE_PRIMARY); 193 if (device && device->vsyncControl(true)) { 194 mVsyncSource = IDisplayDevice::DEVICE_PRIMARY; 195 return true; 196 } 197 } 198 ETRACE("failed to enable vsync on the primary display"); 199 return false; 200 } 201 202 void VsyncManager::disableVsync() 203 { 204 if (mVsyncSource == IDisplayDevice::DEVICE_COUNT) { 205 WTRACE("vsync has been disabled"); 206 return; 207 } 208 209 IDisplayDevice *device = getDisplayDevice(mVsyncSource); 210 if (device && !device->vsyncControl(false)) { 211 WTRACE("failed to disable vsync on device %d", mVsyncSource); 212 } 213 mVsyncSource = IDisplayDevice::DEVICE_COUNT; 214 } 215 216 } // namespace intel 217 } // namespace android 218 219