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