Home | History | Annotate | Download | only in base
      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