• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (c) 2014 Intel Corporation 
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 #include <HwcTrace.h>
17 #include <VsyncEventObserver.h>
18 #include <PhysicalDevice.h>
19 
20 namespace android {
21 namespace intel {
22 
VsyncEventObserver(PhysicalDevice & disp)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 
~VsyncEventObserver()36 VsyncEventObserver::~VsyncEventObserver()
37 {
38     WARN_IF_NOT_DEINIT();
39 }
40 
initialize()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 
deinitialize()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 
control(bool enabled)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 
threadLoop()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