Home | History | Annotate | Download | only in observers
      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 #include <HwcTrace.h>
     17 #include <VsyncEventObserver.h>
     18 #include <PhysicalDevice.h>
     19 
     20 namespace android {
     21 namespace intel {
     22 
     23 VsyncEventObserver::VsyncEventObserver(PhysicalDevice& disp)
     24     : mLock(),
     25       mCondition(),
     26       mDisplayDevice(disp),
     27       mVsyncControl(NULL),
     28       mDevice(IDisplayDevice::DEVICE_COUNT),
     29       mEnabled(false),
     30       mExitThread(false),
     31       mInitialized(false),
     32       mFpsCounter(0)
     33 {
     34     CTRACE();
     35 }
     36 
     37 VsyncEventObserver::~VsyncEventObserver()
     38 {
     39     WARN_IF_NOT_DEINIT();
     40 }
     41 
     42 bool VsyncEventObserver::initialize()
     43 {
     44     if (mInitialized) {
     45         WTRACE("object has been initialized");
     46         return true;
     47     }
     48 
     49     mExitThread = false;
     50     mEnabled = false;
     51     mDevice = mDisplayDevice.getType();
     52     mVsyncControl = mDisplayDevice.createVsyncControl();
     53     if (!mVsyncControl || !mVsyncControl->initialize()) {
     54         DEINIT_AND_RETURN_FALSE("failed to initialize vsync control");
     55     }
     56 
     57     mThread = new VsyncEventPollThread(this);
     58     if (!mThread.get()) {
     59         DEINIT_AND_RETURN_FALSE("failed to create vsync event poll thread.");
     60     }
     61 
     62     mThread->run("VsyncEventObserver", PRIORITY_URGENT_DISPLAY);
     63 
     64     mInitialized = true;
     65     return true;
     66 }
     67 
     68 void VsyncEventObserver::deinitialize()
     69 {
     70     if (mEnabled) {
     71         WTRACE("vsync is still enabled");
     72         control(false);
     73     }
     74     mInitialized = false;
     75     mExitThread = true;
     76     mEnabled = false;
     77     mCondition.signal();
     78 
     79     if (mThread.get()) {
     80         mThread->requestExitAndWait();
     81         mThread = NULL;
     82     }
     83 
     84     DEINIT_AND_DELETE_OBJ(mVsyncControl);
     85 }
     86 
     87 bool VsyncEventObserver::control(bool enabled)
     88 {
     89     ATRACE("enabled = %d on device %d", enabled, mDevice);
     90     if (enabled == mEnabled) {
     91         WTRACE("vsync state %d is not changed", enabled);
     92         return true;
     93     }
     94 
     95     Mutex::Autolock _l(mLock);
     96     bool ret = mVsyncControl->control(mDevice, enabled);
     97     if (!ret) {
     98         ETRACE("failed to control (%d) vsync on display %d", enabled, mDevice);
     99         return false;
    100     }
    101 
    102     mEnabled = enabled;
    103     mCondition.signal();
    104     return true;
    105 }
    106 
    107 bool VsyncEventObserver::threadLoop()
    108 {
    109     do {
    110         // scope for lock
    111         Mutex::Autolock _l(mLock);
    112         while (!mEnabled) {
    113             mCondition.wait(mLock);
    114             if (mExitThread) {
    115                 ITRACE("exiting thread loop");
    116                 return false;
    117             }
    118         }
    119     } while (0);
    120 
    121     if(mEnabled && mDisplayDevice.isConnected()) {
    122         int64_t timestamp;
    123         bool ret = mVsyncControl->wait(mDevice, timestamp);
    124         if (ret == false) {
    125             WTRACE("failed to wait for vsync on display %d, vsync enabled %d", mDevice, mEnabled);
    126             usleep(16000);
    127             return true;
    128         }
    129 
    130         // send vsync event notification every hwc.fps_divider
    131         if ((mFpsCounter++) % mDisplayDevice.getFpsDivider() == 0)
    132             mDisplayDevice.onVsync(timestamp);
    133     }
    134 
    135     return true;
    136 }
    137 
    138 } // namespace intel
    139 } // namesapce android
    140