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 #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